Merge remote-tracking branch 'origin/Graphics-update'
Former-commit-id: 6050b694c2c97ec65e7573d729985e5b7aacec84
This commit is contained in:
commit
ac9e200e83
|
|
@ -38,7 +38,6 @@
|
||||||
#include <Nazara/Graphics/Graphics.hpp>
|
#include <Nazara/Graphics/Graphics.hpp>
|
||||||
#include <Nazara/Graphics/Light.hpp>
|
#include <Nazara/Graphics/Light.hpp>
|
||||||
#include <Nazara/Graphics/Model.hpp>
|
#include <Nazara/Graphics/Model.hpp>
|
||||||
#include <Nazara/Graphics/RenderQueue.hpp>
|
|
||||||
#include <Nazara/Graphics/Scene.hpp>
|
#include <Nazara/Graphics/Scene.hpp>
|
||||||
#include <Nazara/Graphics/SceneNode.hpp>
|
#include <Nazara/Graphics/SceneNode.hpp>
|
||||||
#include <Nazara/Graphics/SceneRoot.hpp>
|
#include <Nazara/Graphics/SceneRoot.hpp>
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,30 @@
|
||||||
|
// Copyright (C) 2013 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
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_ABSTRACTRENDERQUEUE_HPP
|
||||||
|
#define NAZARA_ABSTRACTRENDERQUEUE_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Core/NonCopyable.hpp>
|
||||||
|
|
||||||
|
class NzDrawable;
|
||||||
|
class NzLight;
|
||||||
|
class NzModel;
|
||||||
|
|
||||||
|
class NAZARA_API NzAbstractRenderQueue : NzNonCopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NzAbstractRenderQueue() = default;
|
||||||
|
virtual ~NzAbstractRenderQueue();
|
||||||
|
|
||||||
|
virtual void AddDrawable(const NzDrawable* drawable) = 0;
|
||||||
|
virtual void AddLight(const NzLight* light) = 0;
|
||||||
|
virtual void AddModel(const NzModel* model) = 0;
|
||||||
|
|
||||||
|
virtual void Clear() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_ABSTRACTRENDERQUEUE_HPP
|
||||||
|
|
@ -0,0 +1,29 @@
|
||||||
|
// Copyright (C) 2013 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
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_ABSTRACTRENDERTECHNIQUE_HPP
|
||||||
|
#define NAZARA_ABSTRACTRENDERTECHNIQUE_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Core/NonCopyable.hpp>
|
||||||
|
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
|
||||||
|
|
||||||
|
class NzBackground;
|
||||||
|
class NzScene;
|
||||||
|
|
||||||
|
class NAZARA_API NzAbstractRenderTechnique : NzNonCopyable
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NzAbstractRenderTechnique() = default;
|
||||||
|
virtual ~NzAbstractRenderTechnique();
|
||||||
|
|
||||||
|
virtual void Clear(const NzScene* scene) = 0;
|
||||||
|
virtual void Draw(const NzScene* scene) = 0;
|
||||||
|
|
||||||
|
virtual NzAbstractRenderQueue* GetRenderQueue() = 0;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_ABSTRACTRENDERTECHNIQUE_HPP
|
||||||
|
|
@ -22,7 +22,7 @@ class NAZARA_API NzCamera : public NzSceneNode
|
||||||
NzCamera();
|
NzCamera();
|
||||||
~NzCamera();
|
~NzCamera();
|
||||||
|
|
||||||
void Activate() const;
|
void Activate();
|
||||||
|
|
||||||
void EnsureFrustumUpdate() const;
|
void EnsureFrustumUpdate() const;
|
||||||
void EnsureProjectionMatrixUpdate() const;
|
void EnsureProjectionMatrixUpdate() const;
|
||||||
|
|
@ -50,7 +50,7 @@ class NAZARA_API NzCamera : public NzSceneNode
|
||||||
void SetZNear(float zNear);
|
void SetZNear(float zNear);
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void AddToRenderQueue(NzRenderQueue& renderQueue) const;
|
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
|
||||||
void Invalidate();
|
void Invalidate();
|
||||||
void Register();
|
void Register();
|
||||||
void Unregister();
|
void Unregister();
|
||||||
|
|
|
||||||
|
|
@ -2,60 +2,49 @@
|
||||||
// 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
|
||||||
|
|
||||||
#ifndef NAZARA_RENDERQUEUE_HPP
|
#pragma once
|
||||||
#define NAZARA_RENDERQUEUE_HPP
|
|
||||||
|
#ifndef NAZARA_FORWARDRENDERQUEUE_HPP
|
||||||
|
#define NAZARA_FORWARDRENDERQUEUE_HPP
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
|
||||||
#include <Nazara/Math/Matrix4.hpp>
|
#include <Nazara/Math/Matrix4.hpp>
|
||||||
#include <Nazara/Utility/Mesh.hpp>
|
|
||||||
#include <map>
|
#include <map>
|
||||||
#include <vector>
|
|
||||||
|
|
||||||
class NzDrawable;
|
class NzCamera;
|
||||||
class NzLight;
|
|
||||||
class NzMaterial;
|
class NzMaterial;
|
||||||
class NzModel;
|
|
||||||
class NzSkeletalMesh;
|
class NzSkeletalMesh;
|
||||||
class NzStaticMesh;
|
class NzStaticMesh;
|
||||||
|
|
||||||
class NAZARA_API NzRenderQueue
|
class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue
|
||||||
{
|
{
|
||||||
|
friend class NzForwardRenderTechnique;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
NzRenderQueue() = default;
|
NzForwardRenderQueue() = default;
|
||||||
~NzRenderQueue() = default;
|
~NzForwardRenderQueue() = default;
|
||||||
|
|
||||||
|
void AddDrawable(const NzDrawable* drawable);
|
||||||
|
void AddLight(const NzLight* light);
|
||||||
|
void AddModel(const NzModel* model);
|
||||||
|
|
||||||
void Clear();
|
void Clear();
|
||||||
|
|
||||||
struct SkeletalData
|
void Sort(const NzCamera& camera);
|
||||||
{
|
|
||||||
NzMatrix4f transformMatrix;
|
|
||||||
|
|
||||||
///TODO: Déplacer vers un container séparé qui ne serait pas sujet à Clear();
|
|
||||||
std::vector<NzMeshVertex> skinnedVertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TransparentModel
|
|
||||||
{
|
|
||||||
NzMatrix4f transformMatrix;
|
|
||||||
NzMaterial* material;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TransparentSkeletalModel : public TransparentModel
|
|
||||||
{
|
|
||||||
///TODO: Déplacer vers un container séparé qui ne serait pas sujet à Clear();
|
|
||||||
std::vector<NzMeshVertex> skinnedVertices;
|
|
||||||
};
|
|
||||||
|
|
||||||
struct TransparentStaticModel : public TransparentModel
|
|
||||||
{
|
|
||||||
NzStaticMesh* mesh;
|
|
||||||
};
|
|
||||||
|
|
||||||
|
private:
|
||||||
struct MaterialComparator
|
struct MaterialComparator
|
||||||
{
|
{
|
||||||
bool operator()(const NzMaterial* mat1, const NzMaterial* mat2);
|
bool operator()(const NzMaterial* mat1, const NzMaterial* mat2);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct SkeletalData
|
||||||
|
{
|
||||||
|
///TODO
|
||||||
|
NzMatrix4f transformMatrix;
|
||||||
|
};
|
||||||
|
|
||||||
struct SkeletalMeshComparator
|
struct SkeletalMeshComparator
|
||||||
{
|
{
|
||||||
bool operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2);
|
bool operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2);
|
||||||
|
|
@ -66,16 +55,32 @@ class NAZARA_API NzRenderQueue
|
||||||
bool operator()(const NzStaticMesh* subMesh1, const NzStaticMesh* subMesh2);
|
bool operator()(const NzStaticMesh* subMesh1, const NzStaticMesh* subMesh2);
|
||||||
};
|
};
|
||||||
|
|
||||||
|
struct TransparentModel
|
||||||
|
{
|
||||||
|
NzMatrix4f transformMatrix;
|
||||||
|
NzMaterial* material;
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TransparentSkeletalModel : public TransparentModel
|
||||||
|
{
|
||||||
|
///TODO
|
||||||
|
};
|
||||||
|
|
||||||
|
struct TransparentStaticModel : public TransparentModel
|
||||||
|
{
|
||||||
|
NzStaticMesh* mesh;
|
||||||
|
};
|
||||||
|
|
||||||
typedef std::map<NzSkeletalMesh*, std::vector<SkeletalData>, SkeletalMeshComparator> SkeletalMeshContainer;
|
typedef std::map<NzSkeletalMesh*, std::vector<SkeletalData>, SkeletalMeshComparator> SkeletalMeshContainer;
|
||||||
typedef std::map<NzStaticMesh*, std::vector<NzMatrix4f>, StaticMeshComparator> StaticMeshContainer;
|
typedef std::map<NzStaticMesh*, std::vector<NzMatrix4f>, StaticMeshComparator> StaticMeshContainer;
|
||||||
|
|
||||||
std::map<NzMaterial*, SkeletalMeshContainer, MaterialComparator> visibleSkeletalModels;
|
std::map<NzMaterial*, std::pair<SkeletalMeshContainer, StaticMeshContainer>, MaterialComparator> visibleModels;
|
||||||
std::map<NzMaterial*, StaticMeshContainer, MaterialComparator> visibleStaticModels;
|
std::vector<std::pair<unsigned int, bool>> visibleTransparentsModels;
|
||||||
std::vector<TransparentSkeletalModel> visibleTransparentSkeletalModels;
|
std::vector<TransparentSkeletalModel> transparentSkeletalModels;
|
||||||
std::vector<TransparentStaticModel> visibleTransparentStaticModels;
|
std::vector<TransparentStaticModel> transparentStaticModels;
|
||||||
std::vector<const NzDrawable*> otherDrawables;
|
std::vector<const NzDrawable*> otherDrawables;
|
||||||
std::vector<const NzLight*> directionnalLights;
|
std::vector<const NzLight*> directionnalLights;
|
||||||
std::vector<const NzLight*> visibleLights;
|
std::vector<const NzLight*> visibleLights;
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // NAZARA_RENDERQUEUE_HPP
|
#endif // NAZARA_FORWARDRENDERQUEUE_HPP
|
||||||
|
|
@ -0,0 +1,33 @@
|
||||||
|
// Copyright (C) 2013 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
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#ifndef NAZARA_FORWARDRENDERTECHNIQUE_HPP
|
||||||
|
#define NAZARA_FORWARDRENDERTECHNIQUE_HPP
|
||||||
|
|
||||||
|
#include <Nazara/Prerequesites.hpp>
|
||||||
|
#include <Nazara/Graphics/AbstractRenderTechnique.hpp>
|
||||||
|
#include <Nazara/Graphics/ForwardRenderQueue.hpp>
|
||||||
|
|
||||||
|
class NAZARA_API NzForwardRenderTechnique : public NzAbstractRenderTechnique
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
NzForwardRenderTechnique();
|
||||||
|
~NzForwardRenderTechnique() = default;
|
||||||
|
|
||||||
|
void Clear(const NzScene* scene);
|
||||||
|
void Draw(const NzScene* scene);
|
||||||
|
|
||||||
|
unsigned int GetMaxLightsPerObject() const;
|
||||||
|
NzAbstractRenderQueue* GetRenderQueue() override;
|
||||||
|
|
||||||
|
void SetMaxLightsPerObject(unsigned int lightCount);
|
||||||
|
|
||||||
|
private:
|
||||||
|
NzForwardRenderQueue m_renderQueue;
|
||||||
|
unsigned int m_maxLightsPerObject;
|
||||||
|
};
|
||||||
|
|
||||||
|
#endif // NAZARA_FORWARDRENDERTECHNIQUE_HPP
|
||||||
|
|
@ -19,9 +19,9 @@ class NAZARA_API NzLight : public NzSceneNode
|
||||||
public:
|
public:
|
||||||
NzLight(nzLightType type);
|
NzLight(nzLightType type);
|
||||||
NzLight(const NzLight& light);
|
NzLight(const NzLight& light);
|
||||||
~NzLight();
|
~NzLight() = default;
|
||||||
|
|
||||||
void AddToRenderQueue(NzRenderQueue& renderQueue) const;
|
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
|
||||||
|
|
||||||
void Apply(const NzShader* shader, unsigned int lightUnit) const;
|
void Apply(const NzShader* shader, unsigned int lightUnit) const;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -41,7 +41,7 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
|
||||||
NzModel(NzModel&& model);
|
NzModel(NzModel&& model);
|
||||||
~NzModel();
|
~NzModel();
|
||||||
|
|
||||||
void AddToRenderQueue(NzRenderQueue& renderQueue) const;
|
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
|
||||||
void AdvanceAnimation(float elapsedTime);
|
void AdvanceAnimation(float elapsedTime);
|
||||||
|
|
||||||
void EnableAnimation(bool animation);
|
void EnableAnimation(bool animation);
|
||||||
|
|
@ -64,6 +64,7 @@ class NAZARA_API NzModel : public NzSceneNode, public NzUpdatable
|
||||||
bool HasAnimation() const;
|
bool HasAnimation() const;
|
||||||
|
|
||||||
bool IsAnimationEnabled() const;
|
bool IsAnimationEnabled() const;
|
||||||
|
bool IsDrawable() const;
|
||||||
bool IsDrawEnabled() const;
|
bool IsDrawEnabled() const;
|
||||||
|
|
||||||
bool LoadFromFile(const NzString& filePath, const NzModelParameters& params = NzModelParameters());
|
bool LoadFromFile(const NzString& filePath, const NzModelParameters& params = NzModelParameters());
|
||||||
|
|
|
||||||
|
|
@ -10,9 +10,11 @@
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Core/Color.hpp>
|
#include <Nazara/Core/Color.hpp>
|
||||||
#include <Nazara/Core/Updatable.hpp>
|
#include <Nazara/Core/Updatable.hpp>
|
||||||
|
#include <Nazara/Graphics/AbstractRenderTechnique.hpp>
|
||||||
#include <Nazara/Graphics/Background.hpp>
|
#include <Nazara/Graphics/Background.hpp>
|
||||||
#include <Nazara/Math/Frustum.hpp>
|
#include <Nazara/Math/Frustum.hpp>
|
||||||
|
|
||||||
|
class NzAbstractRenderQueue;
|
||||||
class NzCamera;
|
class NzCamera;
|
||||||
class NzLight;
|
class NzLight;
|
||||||
class NzModel;
|
class NzModel;
|
||||||
|
|
@ -34,8 +36,10 @@ class NAZARA_API NzScene
|
||||||
void Cull();
|
void Cull();
|
||||||
void Draw();
|
void Draw();
|
||||||
|
|
||||||
const NzCamera* GetActiveCamera() const;
|
NzCamera* GetActiveCamera() const;
|
||||||
|
NzColor GetAmbientColor() const;
|
||||||
NzBackground* GetBackground() const;
|
NzBackground* GetBackground() const;
|
||||||
|
NzAbstractRenderTechnique* GetRenderTechnique() const;
|
||||||
NzSceneNode& GetRoot() const;
|
NzSceneNode& GetRoot() const;
|
||||||
float GetUpdateTime() const;
|
float GetUpdateTime() const;
|
||||||
unsigned int GetUpdatePerSecond() const;
|
unsigned int GetUpdatePerSecond() const;
|
||||||
|
|
@ -44,6 +48,7 @@ class NAZARA_API NzScene
|
||||||
|
|
||||||
void SetAmbientColor(const NzColor& color);
|
void SetAmbientColor(const NzColor& color);
|
||||||
void SetBackground(NzBackground* background);
|
void SetBackground(NzBackground* background);
|
||||||
|
void SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique);
|
||||||
void SetUpdatePerSecond(unsigned int updatePerSecond);
|
void SetUpdatePerSecond(unsigned int updatePerSecond);
|
||||||
|
|
||||||
void UnregisterForUpdate(NzUpdatable* object);
|
void UnregisterForUpdate(NzUpdatable* object);
|
||||||
|
|
@ -54,8 +59,8 @@ class NAZARA_API NzScene
|
||||||
operator const NzSceneNode&() const;
|
operator const NzSceneNode&() const;
|
||||||
|
|
||||||
private:
|
private:
|
||||||
void RecursiveFrustumCull(NzRenderQueue& renderQueue, const NzFrustumf& frustum, NzNode* node);
|
void RecursiveFrustumCull(NzAbstractRenderQueue* renderQueue, const NzFrustumf& frustum, NzNode* node);
|
||||||
void SetActiveCamera(const NzCamera* camera);
|
void SetActiveCamera(NzCamera* camera);
|
||||||
|
|
||||||
NzSceneImpl* m_impl;
|
NzSceneImpl* m_impl;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -9,7 +9,6 @@
|
||||||
|
|
||||||
#include <Nazara/Prerequesites.hpp>
|
#include <Nazara/Prerequesites.hpp>
|
||||||
#include <Nazara/Graphics/Enums.hpp>
|
#include <Nazara/Graphics/Enums.hpp>
|
||||||
#include <Nazara/Graphics/RenderQueue.hpp>
|
|
||||||
#include <Nazara/Graphics/Scene.hpp>
|
#include <Nazara/Graphics/Scene.hpp>
|
||||||
#include <Nazara/Math/BoundingBox.hpp>
|
#include <Nazara/Math/BoundingBox.hpp>
|
||||||
#include <Nazara/Math/Frustum.hpp>
|
#include <Nazara/Math/Frustum.hpp>
|
||||||
|
|
@ -24,7 +23,7 @@ class NAZARA_API NzSceneNode : public NzNode
|
||||||
NzSceneNode(const NzSceneNode& node);
|
NzSceneNode(const NzSceneNode& node);
|
||||||
virtual ~NzSceneNode();
|
virtual ~NzSceneNode();
|
||||||
|
|
||||||
virtual void AddToRenderQueue(NzRenderQueue& renderQueue) const = 0;
|
virtual void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const = 0;
|
||||||
|
|
||||||
virtual const NzBoundingBoxf& GetBoundingBox() const = 0;
|
virtual const NzBoundingBoxf& GetBoundingBox() const = 0;
|
||||||
nzNodeType GetNodeType() const final;
|
nzNodeType GetNodeType() const final;
|
||||||
|
|
|
||||||
|
|
@ -17,7 +17,7 @@ class NAZARA_API NzSceneRoot : public NzSceneNode
|
||||||
friend struct NzSceneImpl;
|
friend struct NzSceneImpl;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
void AddToRenderQueue(NzRenderQueue& renderQueue) const override;
|
void AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const override;
|
||||||
|
|
||||||
const NzBoundingBoxf& GetBoundingBox() const override;
|
const NzBoundingBoxf& GetBoundingBox() const override;
|
||||||
nzSceneNodeType GetSceneNodeType() const override;
|
nzSceneNodeType GetSceneNodeType() const override;
|
||||||
|
|
|
||||||
|
|
@ -30,7 +30,7 @@
|
||||||
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
/// Chaque modification d'un paramètre du module nécessite une recompilation de celui-ci
|
||||||
|
|
||||||
// Le nombre maximum d'instances pouvant être géré par le Renderer
|
// Le nombre maximum d'instances pouvant être géré par le Renderer
|
||||||
#define NAZARA_RENDERER_INSTANCING_MAX 8192
|
#define NAZARA_RENDERER_MAX_INSTANCES 8192
|
||||||
|
|
||||||
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
// Utilise un tracker pour repérer les éventuels leaks (Ralentit l'exécution)
|
||||||
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 0
|
#define NAZARA_RENDERER_MEMORYLEAKTRACKER 0
|
||||||
|
|
@ -41,4 +41,7 @@
|
||||||
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
// Active les tests de sécurité basés sur le code (Conseillé pour le développement)
|
||||||
#define NAZARA_RENDERER_SAFE 1
|
#define NAZARA_RENDERER_SAFE 1
|
||||||
|
|
||||||
|
// Le nombre maximum de lumières qu'un forward shader supportera
|
||||||
|
#define NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT 8
|
||||||
|
|
||||||
#endif // NAZARA_CONFIG_MODULENAME_HPP
|
#endif // NAZARA_CONFIG_MODULENAME_HPP
|
||||||
|
|
|
||||||
|
|
@ -107,7 +107,7 @@ class NAZARA_API NzOpenGL
|
||||||
static GLenum ElementType[nzElementType_Max+1];
|
static GLenum ElementType[nzElementType_Max+1];
|
||||||
static GLenum FaceCulling[nzFaceCulling_Max+1];
|
static GLenum FaceCulling[nzFaceCulling_Max+1];
|
||||||
static GLenum FaceFilling[nzFaceFilling_Max+1];
|
static GLenum FaceFilling[nzFaceFilling_Max+1];
|
||||||
static GLenum PrimitiveType[nzPrimitiveType_Max+1];
|
static GLenum PrimitiveMode[nzPrimitiveMode_Max+1];
|
||||||
static GLenum RendererComparison[nzRendererComparison_Max+1];
|
static GLenum RendererComparison[nzRendererComparison_Max+1];
|
||||||
static GLenum RendererParameter[nzRendererParameter_Max+1];
|
static GLenum RendererParameter[nzRendererParameter_Max+1];
|
||||||
static GLenum SamplerWrapMode[nzSamplerWrap_Max+1];
|
static GLenum SamplerWrapMode[nzSamplerWrap_Max+1];
|
||||||
|
|
|
||||||
|
|
@ -36,10 +36,10 @@ class NAZARA_API NzRenderer
|
||||||
|
|
||||||
static void Clear(unsigned long flags = nzRendererClear_Color | nzRendererClear_Depth);
|
static void Clear(unsigned long flags = nzRendererClear_Color | nzRendererClear_Depth);
|
||||||
|
|
||||||
static void DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount);
|
static void DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount);
|
||||||
static void DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount);
|
static void DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount);
|
||||||
static void DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount);
|
static void DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount);
|
||||||
static void DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount);
|
static void DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount);
|
||||||
NAZARA_DEPRECATED("Don't use this or you will have cancer") static void DrawTexture(unsigned int unit, const NzRectf& rect, const NzVector2f& uv0, const NzVector2f& uv1, float z = 0.f);
|
NAZARA_DEPRECATED("Don't use this or you will have cancer") static void DrawTexture(unsigned int unit, const NzRectf& rect, const NzVector2f& uv0, const NzVector2f& uv1, float z = 0.f);
|
||||||
|
|
||||||
static void Enable(nzRendererParameter parameter, bool enable);
|
static void Enable(nzRendererParameter parameter, bool enable);
|
||||||
|
|
|
||||||
|
|
@ -205,16 +205,16 @@ enum nzPixelFlipping
|
||||||
nzPixelFlipping_Max = nzPixelFlipping_Vertically
|
nzPixelFlipping_Max = nzPixelFlipping_Vertically
|
||||||
};
|
};
|
||||||
|
|
||||||
enum nzPrimitiveType
|
enum nzPrimitiveMode
|
||||||
{
|
{
|
||||||
nzPrimitiveType_LineList,
|
nzPrimitiveMode_LineList,
|
||||||
nzPrimitiveType_LineStrip,
|
nzPrimitiveMode_LineStrip,
|
||||||
nzPrimitiveType_PointList,
|
nzPrimitiveMode_PointList,
|
||||||
nzPrimitiveType_TriangleList,
|
nzPrimitiveMode_TriangleList,
|
||||||
nzPrimitiveType_TriangleStrip,
|
nzPrimitiveMode_TriangleStrip,
|
||||||
nzPrimitiveType_TriangleFan,
|
nzPrimitiveMode_TriangleFan,
|
||||||
|
|
||||||
nzPrimitiveType_Max = nzPrimitiveType_TriangleFan
|
nzPrimitiveMode_Max = nzPrimitiveMode_TriangleFan
|
||||||
};
|
};
|
||||||
|
|
||||||
enum nzWindowCursor
|
enum nzWindowCursor
|
||||||
|
|
|
||||||
|
|
@ -39,17 +39,17 @@ class NAZARA_API NzSubMesh : public NzResource
|
||||||
virtual const NzIndexBuffer* GetIndexBuffer() const = 0;
|
virtual const NzIndexBuffer* GetIndexBuffer() const = 0;
|
||||||
unsigned int GetMaterialIndex() const;
|
unsigned int GetMaterialIndex() const;
|
||||||
const NzMesh* GetParent() const;
|
const NzMesh* GetParent() const;
|
||||||
nzPrimitiveType GetPrimitiveType() const;
|
nzPrimitiveMode GetPrimitiveMode() const;
|
||||||
unsigned int GetTriangleCount() const;
|
unsigned int GetTriangleCount() const;
|
||||||
virtual unsigned int GetVertexCount() const = 0;
|
virtual unsigned int GetVertexCount() const = 0;
|
||||||
|
|
||||||
virtual bool IsAnimated() const = 0;
|
virtual bool IsAnimated() const = 0;
|
||||||
|
|
||||||
void SetMaterialIndex(unsigned int matIndex);
|
void SetMaterialIndex(unsigned int matIndex);
|
||||||
void SetPrimitiveType(nzPrimitiveType primitiveType);
|
void SetPrimitiveMode(nzPrimitiveMode mode);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
nzPrimitiveType m_primitiveType;
|
nzPrimitiveMode m_primitiveMode;
|
||||||
const NzMesh* m_parent;
|
const NzMesh* m_parent;
|
||||||
unsigned int m_matIndex;
|
unsigned int m_matIndex;
|
||||||
};
|
};
|
||||||
|
|
|
||||||
|
|
@ -37,7 +37,7 @@ class NAZARA_API NzTriangleIterator
|
||||||
void Unmap();
|
void Unmap();
|
||||||
|
|
||||||
private:
|
private:
|
||||||
nzPrimitiveType m_primitiveType;
|
nzPrimitiveMode m_primitiveMode;
|
||||||
nzUInt32 m_triangleIndices[3];
|
nzUInt32 m_triangleIndices[3];
|
||||||
NzIndexMapper m_indexMapper;
|
NzIndexMapper m_indexMapper;
|
||||||
NzVertexMapper m_vertexMapper;
|
NzVertexMapper m_vertexMapper;
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Copyright (C) 2013 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/AbstractRenderQueue.hpp>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
NzAbstractRenderQueue::~NzAbstractRenderQueue() = default;
|
||||||
|
|
@ -0,0 +1,8 @@
|
||||||
|
// Copyright (C) 2013 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/AbstractRenderTechnique.hpp>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
NzAbstractRenderTechnique::~NzAbstractRenderTechnique() = default;
|
||||||
|
|
@ -23,7 +23,7 @@ m_zNear(1.f)
|
||||||
|
|
||||||
NzCamera::~NzCamera() = default;
|
NzCamera::~NzCamera() = default;
|
||||||
|
|
||||||
void NzCamera::Activate() const
|
void NzCamera::Activate()
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_GRAPHICS_SAFE
|
#ifdef NAZARA_GRAPHICS_SAFE
|
||||||
if (!m_target)
|
if (!m_target)
|
||||||
|
|
@ -206,7 +206,7 @@ void NzCamera::SetZNear(float zNear)
|
||||||
m_projectionMatrixUpdated = false;
|
m_projectionMatrixUpdated = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzCamera::AddToRenderQueue(NzRenderQueue& renderQueue) const
|
void NzCamera::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
|
||||||
{
|
{
|
||||||
NazaraUnused(renderQueue);
|
NazaraUnused(renderQueue);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -0,0 +1,224 @@
|
||||||
|
// Copyright (C) 2013 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/ForwardRenderQueue.hpp>
|
||||||
|
#include <Nazara/Graphics/Camera.hpp>
|
||||||
|
#include <Nazara/Graphics/Light.hpp>
|
||||||
|
#include <Nazara/Graphics/Model.hpp>
|
||||||
|
#include <Nazara/Renderer/Material.hpp>
|
||||||
|
#include <Nazara/Utility/SkeletalMesh.hpp>
|
||||||
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
void NzForwardRenderQueue::AddDrawable(const NzDrawable* drawable)
|
||||||
|
{
|
||||||
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
if (!drawable)
|
||||||
|
{
|
||||||
|
NazaraError("Invalid drawable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
otherDrawables.push_back(drawable);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderQueue::AddLight(const NzLight* light)
|
||||||
|
{
|
||||||
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
if (!light)
|
||||||
|
{
|
||||||
|
NazaraError("Invalid light");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
switch (light->GetLightType())
|
||||||
|
{
|
||||||
|
case nzLightType_Directional:
|
||||||
|
directionnalLights.push_back(light);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case nzLightType_Point:
|
||||||
|
case nzLightType_Spot:
|
||||||
|
visibleLights.push_back(light);
|
||||||
|
break;
|
||||||
|
|
||||||
|
#ifdef NAZARA_DEBUG
|
||||||
|
default:
|
||||||
|
NazaraError("Light type not handled (0x" + NzString::Number(light->GetLightType(), 16) + ')');
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderQueue::AddModel(const NzModel* model)
|
||||||
|
{
|
||||||
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
|
if (!model)
|
||||||
|
{
|
||||||
|
NazaraError("Invalid model");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!model->IsDrawable())
|
||||||
|
{
|
||||||
|
NazaraError("Model is not drawable");
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const NzMatrix4f& transformMatrix = model->GetTransformMatrix();
|
||||||
|
|
||||||
|
NzMesh* mesh = model->GetMesh();
|
||||||
|
unsigned int submeshCount = mesh->GetSubMeshCount();
|
||||||
|
|
||||||
|
for (unsigned int i = 0; i < submeshCount; ++i)
|
||||||
|
{
|
||||||
|
NzSubMesh* subMesh = mesh->GetSubMesh(i);
|
||||||
|
NzMaterial* material = model->GetMaterial(subMesh->GetMaterialIndex());
|
||||||
|
|
||||||
|
switch (subMesh->GetAnimationType())
|
||||||
|
{
|
||||||
|
case nzAnimationType_Skeletal:
|
||||||
|
{
|
||||||
|
///TODO
|
||||||
|
/*
|
||||||
|
** Il y a ici deux choses importantes à gérer:
|
||||||
|
** -Pour commencer, la mise en cache de std::vector suffisamment grands pour contenir le résultat du skinning
|
||||||
|
** l'objectif ici est d'éviter une allocation à chaque frame, donc de réutiliser un tableau existant
|
||||||
|
** Note: Il faudrait évaluer aussi la possibilité de conserver le buffer d'une frame à l'autre.
|
||||||
|
** Ceci permettant de ne pas skinner inutilement ce qui ne bouge pas, ou de skinner partiellement un mesh.
|
||||||
|
** Il faut cependant voir où stocker ce set de buffers, qui doit être communs à toutes les RQ d'une même scène.
|
||||||
|
**
|
||||||
|
** -Ensuite, la possibilité de regrouper les modèles skinnés identiques, une centaine de soldats marchant au pas
|
||||||
|
** ne devrait requérir qu'un skinning.
|
||||||
|
*/
|
||||||
|
NazaraError("Skeletal mesh not supported yet, sorry");
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case nzAnimationType_Static:
|
||||||
|
{
|
||||||
|
NzStaticMesh* staticMesh = static_cast<NzStaticMesh*>(subMesh);
|
||||||
|
if (material->IsAlphaBlendingEnabled())
|
||||||
|
{
|
||||||
|
unsigned int index = transparentStaticModels.size();
|
||||||
|
transparentStaticModels.resize(index+1);
|
||||||
|
|
||||||
|
TransparentStaticModel& data = transparentStaticModels.back();
|
||||||
|
data.material = material;
|
||||||
|
data.mesh = staticMesh;
|
||||||
|
data.transformMatrix = transformMatrix;
|
||||||
|
|
||||||
|
visibleTransparentsModels.push_back(std::make_pair(index, true));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
visibleModels[material].second[staticMesh].push_back(transformMatrix);
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderQueue::Clear()
|
||||||
|
{
|
||||||
|
directionnalLights.clear();
|
||||||
|
otherDrawables.clear();
|
||||||
|
visibleLights.clear();
|
||||||
|
visibleModels.clear();
|
||||||
|
visibleTransparentsModels.clear();
|
||||||
|
transparentSkeletalModels.clear();
|
||||||
|
transparentStaticModels.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderQueue::Sort(const NzCamera& camera)
|
||||||
|
{
|
||||||
|
struct TransparentModelComparator
|
||||||
|
{
|
||||||
|
bool operator()(const std::pair<unsigned int, bool>& index1, const std::pair<unsigned int, bool>& index2)
|
||||||
|
{
|
||||||
|
const NzMatrix4f& matrix1 = (index1.second) ?
|
||||||
|
queue->transparentStaticModels[index1.first].transformMatrix :
|
||||||
|
queue->transparentSkeletalModels[index1.first].transformMatrix;
|
||||||
|
|
||||||
|
const NzMatrix4f& matrix2 = (index1.second) ?
|
||||||
|
queue->transparentStaticModels[index2.first].transformMatrix :
|
||||||
|
queue->transparentSkeletalModels[index2.first].transformMatrix;
|
||||||
|
|
||||||
|
return nearPlane.Distance(matrix1.GetTranslation()) < nearPlane.Distance(matrix2.GetTranslation());
|
||||||
|
}
|
||||||
|
|
||||||
|
NzForwardRenderQueue* queue;
|
||||||
|
NzPlanef nearPlane;
|
||||||
|
};
|
||||||
|
|
||||||
|
TransparentModelComparator comparator {this, camera.GetFrustum().GetPlane(nzFrustumPlane_Near)};
|
||||||
|
std::sort(visibleTransparentsModels.begin(), visibleTransparentsModels.end(), comparator);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzForwardRenderQueue::SkeletalMeshComparator::operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2)
|
||||||
|
{
|
||||||
|
const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer();
|
||||||
|
const NzBuffer* buffer1 = (iBuffer1) ? iBuffer1->GetBuffer() : nullptr;
|
||||||
|
|
||||||
|
const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer();
|
||||||
|
const NzBuffer* buffer2 = (iBuffer2) ? iBuffer2->GetBuffer() : nullptr;
|
||||||
|
|
||||||
|
if (buffer1 == buffer2)
|
||||||
|
return subMesh1 < subMesh2;
|
||||||
|
else
|
||||||
|
return buffer2 < buffer2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzForwardRenderQueue::StaticMeshComparator::operator()(const NzStaticMesh* subMesh1, const NzStaticMesh* subMesh2)
|
||||||
|
{
|
||||||
|
const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer();
|
||||||
|
const NzBuffer* buffer1 = (iBuffer1) ? iBuffer1->GetBuffer() : nullptr;
|
||||||
|
|
||||||
|
const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer();
|
||||||
|
const NzBuffer* buffer2 = (iBuffer2) ? iBuffer2->GetBuffer() : nullptr;
|
||||||
|
|
||||||
|
if (buffer1 == buffer2)
|
||||||
|
{
|
||||||
|
buffer1 = subMesh1->GetVertexBuffer()->GetBuffer();
|
||||||
|
buffer2 = subMesh2->GetVertexBuffer()->GetBuffer();
|
||||||
|
|
||||||
|
if (buffer1 == buffer2)
|
||||||
|
return subMesh1 < subMesh2;
|
||||||
|
else
|
||||||
|
return buffer1 < buffer2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return buffer1 < buffer2;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool NzForwardRenderQueue::MaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2)
|
||||||
|
{
|
||||||
|
const NzShader* shader1 = mat1->GetCustomShader();
|
||||||
|
const NzShader* shader2 = mat2->GetCustomShader();
|
||||||
|
|
||||||
|
if (shader1)
|
||||||
|
{
|
||||||
|
if (shader2)
|
||||||
|
{
|
||||||
|
if (shader1 != shader2)
|
||||||
|
return shader1 < shader2;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
else if (shader2)
|
||||||
|
return false;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nzUInt32 shaderFlags1 = mat1->GetShaderFlags();
|
||||||
|
nzUInt32 shaderFlags2 = mat2->GetShaderFlags();
|
||||||
|
|
||||||
|
if (shaderFlags1 != shaderFlags2)
|
||||||
|
return shaderFlags1 < shaderFlags2;
|
||||||
|
}
|
||||||
|
|
||||||
|
return mat1 < mat2;
|
||||||
|
}
|
||||||
|
|
@ -0,0 +1,277 @@
|
||||||
|
// Copyright (C) 2013 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/ForwardRenderTechnique.hpp>
|
||||||
|
#include <Nazara/Graphics/Background.hpp>
|
||||||
|
#include <Nazara/Graphics/Camera.hpp>
|
||||||
|
#include <Nazara/Graphics/Drawable.hpp>
|
||||||
|
#include <Nazara/Graphics/Light.hpp>
|
||||||
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
|
#include <Nazara/Renderer/Material.hpp>
|
||||||
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
|
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
||||||
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
|
namespace
|
||||||
|
{
|
||||||
|
struct LightComparator
|
||||||
|
{
|
||||||
|
bool operator()(const NzLight* light1, const NzLight* light2)
|
||||||
|
{
|
||||||
|
return light1->GetPosition().SquaredDistance(pos) < light2->GetPosition().SquaredDistance(pos);
|
||||||
|
}
|
||||||
|
|
||||||
|
NzVector3f pos;
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
NzForwardRenderTechnique::NzForwardRenderTechnique() :
|
||||||
|
m_maxLightsPerObject(3) // Valeur totalement arbitraire
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderTechnique::Clear(const NzScene* scene)
|
||||||
|
{
|
||||||
|
NzRenderer::Enable(nzRendererParameter_DepthBuffer, true);
|
||||||
|
NzRenderer::Enable(nzRendererParameter_DepthWrite, true);
|
||||||
|
NzRenderer::Clear(nzRendererClear_Depth);
|
||||||
|
|
||||||
|
NzBackground* background = scene->GetBackground();
|
||||||
|
if (background)
|
||||||
|
background->Draw(scene);
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
||||||
|
{
|
||||||
|
///TODO: Regrouper les activations par méthode
|
||||||
|
LightComparator lightComparator;
|
||||||
|
|
||||||
|
const NzCamera* camera = scene->GetActiveCamera();
|
||||||
|
const NzShader* lastShader = nullptr;
|
||||||
|
|
||||||
|
// Externes à la boucle pour conserver leur valeurs si le shader ne change pas
|
||||||
|
unsigned int lightCount = 0;
|
||||||
|
int lightCountLocation = -1;
|
||||||
|
|
||||||
|
// Rendu des modèles opaques
|
||||||
|
for (auto matIt : m_renderQueue.visibleModels)
|
||||||
|
{
|
||||||
|
NzMaterial* material = matIt.first;
|
||||||
|
|
||||||
|
// On commence par récupérer le shader du matériau
|
||||||
|
const NzShader* shader;
|
||||||
|
if (material->HasCustomShader())
|
||||||
|
shader = material->GetCustomShader();
|
||||||
|
else
|
||||||
|
shader = NzShaderBuilder::Get(material->GetShaderFlags());
|
||||||
|
|
||||||
|
// Les uniformes sont conservées au sein du shader, inutile de les renvoyer tant que le shader reste le même
|
||||||
|
if (shader != lastShader)
|
||||||
|
{
|
||||||
|
// On récupère l'information sur l'éclairage en même temps que la position de l'uniforme "LightCount"
|
||||||
|
lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount);
|
||||||
|
|
||||||
|
NzRenderer::SetShader(shader);
|
||||||
|
|
||||||
|
// Couleur ambiante de la scène
|
||||||
|
shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor());
|
||||||
|
// Position de la caméra
|
||||||
|
shader->SendVector(shader->GetUniformLocation(nzShaderUniform_CameraPosition), camera->GetPosition());
|
||||||
|
|
||||||
|
lightCount = 0;
|
||||||
|
|
||||||
|
// On envoie les lumières directionnelles s'il y a (Les mêmes pour tous)
|
||||||
|
if (lightCountLocation != -1)
|
||||||
|
{
|
||||||
|
for (const NzLight* light : m_renderQueue.directionnalLights)
|
||||||
|
{
|
||||||
|
light->Apply(shader, lightCount++);
|
||||||
|
if (lightCount > NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT)
|
||||||
|
break; // Prévenons les bêtises des utilisateurs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastShader = shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
material->Apply(shader);
|
||||||
|
|
||||||
|
// Meshs squelettiques
|
||||||
|
/*NzForwardRenderQueue::SkeletalMeshContainer& container = matIt.second.first;
|
||||||
|
if (!container.empty())
|
||||||
|
{
|
||||||
|
NzRenderer::SetVertexBuffer(m_skinningBuffer); // Vertex buffer commun
|
||||||
|
for (auto subMeshIt : container)
|
||||||
|
{
|
||||||
|
///TODO
|
||||||
|
}
|
||||||
|
}*/
|
||||||
|
|
||||||
|
// Meshs statiques
|
||||||
|
for (auto subMeshIt : matIt.second.second)
|
||||||
|
{
|
||||||
|
NzStaticMesh* mesh = subMeshIt.first;
|
||||||
|
|
||||||
|
const NzIndexBuffer* indexBuffer = mesh->GetIndexBuffer();
|
||||||
|
const NzVertexBuffer* vertexBuffer = mesh->GetVertexBuffer();
|
||||||
|
|
||||||
|
// Gestion du draw call avant la boucle de rendu
|
||||||
|
std::function<void(nzPrimitiveMode, unsigned int, unsigned int)> drawFunc;
|
||||||
|
unsigned int indexCount;
|
||||||
|
|
||||||
|
if (indexBuffer)
|
||||||
|
{
|
||||||
|
drawFunc = NzRenderer::DrawIndexedPrimitives;
|
||||||
|
indexCount = indexBuffer->GetIndexCount();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
drawFunc = NzRenderer::DrawPrimitives;
|
||||||
|
indexCount = vertexBuffer->GetVertexCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
NzRenderer::SetIndexBuffer(indexBuffer);
|
||||||
|
NzRenderer::SetVertexBuffer(vertexBuffer);
|
||||||
|
|
||||||
|
for (const NzMatrix4f& matrix : subMeshIt.second)
|
||||||
|
{
|
||||||
|
// Calcul des lumières les plus proches
|
||||||
|
///TODO: LightManager ?
|
||||||
|
if (lightCountLocation != -1)
|
||||||
|
{
|
||||||
|
std::vector<const NzLight*>& visibleLights = m_renderQueue.visibleLights;
|
||||||
|
|
||||||
|
lightComparator.pos = matrix.GetTranslation();
|
||||||
|
std::sort(visibleLights.begin(), visibleLights.end(), lightComparator);
|
||||||
|
|
||||||
|
unsigned int max = std::min(std::min(NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT - lightCount, m_maxLightsPerObject), static_cast<unsigned int>(visibleLights.size()));
|
||||||
|
for (unsigned int i = 0; i < max; ++i)
|
||||||
|
visibleLights[i]->Apply(shader, lightCount++);
|
||||||
|
|
||||||
|
shader->SendInteger(lightCountLocation, lightCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
NzRenderer::SetMatrix(nzMatrixType_World, matrix);
|
||||||
|
drawFunc(mesh->GetPrimitiveMode(), 0, indexCount);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (const std::pair<unsigned int, bool>& pair : m_renderQueue.visibleTransparentsModels)
|
||||||
|
{
|
||||||
|
// Matériau
|
||||||
|
NzMaterial* material = (pair.second) ?
|
||||||
|
m_renderQueue.transparentStaticModels[pair.first].material :
|
||||||
|
m_renderQueue.transparentSkeletalModels[pair.first].material;
|
||||||
|
|
||||||
|
// On commence par récupérer le shader du matériau
|
||||||
|
const NzShader* shader;
|
||||||
|
if (material->HasCustomShader())
|
||||||
|
shader = material->GetCustomShader();
|
||||||
|
else
|
||||||
|
shader = NzShaderBuilder::Get(material->GetShaderFlags());
|
||||||
|
|
||||||
|
// Les uniformes sont conservées au sein du shader, inutile de les renvoyer tant que le shader reste le même
|
||||||
|
if (shader != lastShader)
|
||||||
|
{
|
||||||
|
// On récupère l'information sur l'éclairage en même temps que la position de l'uniforme "LightCount"
|
||||||
|
lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount);
|
||||||
|
|
||||||
|
NzRenderer::SetShader(shader);
|
||||||
|
|
||||||
|
// Couleur ambiante de la scène
|
||||||
|
shader->SendColor(shader->GetUniformLocation(nzShaderUniform_SceneAmbient), scene->GetAmbientColor());
|
||||||
|
// Position de la caméra
|
||||||
|
shader->SendVector(shader->GetUniformLocation(nzShaderUniform_CameraPosition), camera->GetPosition());
|
||||||
|
|
||||||
|
lightCount = 0;
|
||||||
|
|
||||||
|
// On envoie les lumières directionnelles s'il y a (Les mêmes pour tous)
|
||||||
|
if (lightCountLocation != -1)
|
||||||
|
{
|
||||||
|
for (const NzLight* light : m_renderQueue.directionnalLights)
|
||||||
|
{
|
||||||
|
light->Apply(shader, lightCount++);
|
||||||
|
if (lightCount > NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT)
|
||||||
|
break; // Prévenons les bêtises des utilisateurs
|
||||||
|
}
|
||||||
|
}
|
||||||
|
lastShader = shader;
|
||||||
|
}
|
||||||
|
|
||||||
|
material->Apply(shader);
|
||||||
|
|
||||||
|
// Mesh
|
||||||
|
if (pair.second)
|
||||||
|
{
|
||||||
|
NzForwardRenderQueue::TransparentStaticModel& staticModel = m_renderQueue.transparentStaticModels[pair.first];
|
||||||
|
|
||||||
|
const NzMatrix4f& matrix = staticModel.transformMatrix;
|
||||||
|
NzStaticMesh* mesh = staticModel.mesh;
|
||||||
|
|
||||||
|
const NzIndexBuffer* indexBuffer = mesh->GetIndexBuffer();
|
||||||
|
const NzVertexBuffer* vertexBuffer = mesh->GetVertexBuffer();
|
||||||
|
|
||||||
|
// Gestion du draw call avant la boucle de rendu
|
||||||
|
std::function<void(nzPrimitiveMode, unsigned int, unsigned int)> drawFunc;
|
||||||
|
unsigned int indexCount;
|
||||||
|
|
||||||
|
if (indexBuffer)
|
||||||
|
{
|
||||||
|
drawFunc = NzRenderer::DrawIndexedPrimitives;
|
||||||
|
indexCount = indexBuffer->GetIndexCount();
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
drawFunc = NzRenderer::DrawPrimitives;
|
||||||
|
indexCount = vertexBuffer->GetVertexCount();
|
||||||
|
}
|
||||||
|
|
||||||
|
NzRenderer::SetIndexBuffer(indexBuffer);
|
||||||
|
NzRenderer::SetVertexBuffer(vertexBuffer);
|
||||||
|
|
||||||
|
// Calcul des lumières les plus proches
|
||||||
|
///TODO: LightManager ?
|
||||||
|
if (lightCountLocation != -1)
|
||||||
|
{
|
||||||
|
std::vector<const NzLight*>& visibleLights = m_renderQueue.visibleLights;
|
||||||
|
|
||||||
|
lightComparator.pos = matrix.GetTranslation();
|
||||||
|
std::sort(visibleLights.begin(), visibleLights.end(), lightComparator);
|
||||||
|
|
||||||
|
unsigned int max = std::min(std::min(NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT - lightCount, m_maxLightsPerObject), static_cast<unsigned int>(visibleLights.size()));
|
||||||
|
for (unsigned int i = 0; i < max; ++i)
|
||||||
|
visibleLights[i]->Apply(shader, lightCount++);
|
||||||
|
|
||||||
|
shader->SendInteger(lightCountLocation, lightCount);
|
||||||
|
}
|
||||||
|
|
||||||
|
NzRenderer::SetMatrix(nzMatrixType_World, matrix);
|
||||||
|
drawFunc(mesh->GetPrimitiveMode(), 0, indexCount);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
///TODO
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Les autres drawables (Exemple: Terrain)
|
||||||
|
for (const NzDrawable* drawable : m_renderQueue.otherDrawables)
|
||||||
|
drawable->Draw();
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned int NzForwardRenderTechnique::GetMaxLightsPerObject() const
|
||||||
|
{
|
||||||
|
return m_maxLightsPerObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
NzAbstractRenderQueue* NzForwardRenderTechnique::GetRenderQueue()
|
||||||
|
{
|
||||||
|
return &m_renderQueue;
|
||||||
|
}
|
||||||
|
|
||||||
|
void NzForwardRenderTechnique::SetMaxLightsPerObject(unsigned int lightCount)
|
||||||
|
{
|
||||||
|
m_maxLightsPerObject = lightCount;
|
||||||
|
}
|
||||||
|
|
@ -4,6 +4,7 @@
|
||||||
|
|
||||||
#include <Nazara/Graphics/Light.hpp>
|
#include <Nazara/Graphics/Light.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
|
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
|
||||||
#include <Nazara/Math/Basic.hpp>
|
#include <Nazara/Math/Basic.hpp>
|
||||||
#include <Nazara/Math/Sphere.hpp>
|
#include <Nazara/Math/Sphere.hpp>
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
#include <Nazara/Renderer/Renderer.hpp>
|
||||||
|
|
@ -32,23 +33,9 @@ NzSceneNode(light)
|
||||||
std::memcpy(this, &light, sizeof(NzLight)); // Aussi simple que ça
|
std::memcpy(this, &light, sizeof(NzLight)); // Aussi simple que ça
|
||||||
}
|
}
|
||||||
|
|
||||||
NzLight::~NzLight()
|
void NzLight::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
|
||||||
{
|
{
|
||||||
}
|
renderQueue->AddLight(this);
|
||||||
|
|
||||||
void NzLight::AddToRenderQueue(NzRenderQueue& renderQueue) const
|
|
||||||
{
|
|
||||||
switch (m_type)
|
|
||||||
{
|
|
||||||
case nzLightType_Directional:
|
|
||||||
renderQueue.directionnalLights.push_back(this);
|
|
||||||
break;
|
|
||||||
|
|
||||||
case nzLightType_Point:
|
|
||||||
case nzLightType_Spot:
|
|
||||||
renderQueue.visibleLights.push_back(this);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzLight::Apply(const NzShader* shader, unsigned int lightUnit) const
|
void NzLight::Apply(const NzShader* shader, unsigned int lightUnit) const
|
||||||
|
|
|
||||||
|
|
@ -160,7 +160,7 @@ namespace
|
||||||
|
|
||||||
subMesh->GenerateAABB();
|
subMesh->GenerateAABB();
|
||||||
subMesh->SetMaterialIndex(meshes[i].material);
|
subMesh->SetMaterialIndex(meshes[i].material);
|
||||||
subMesh->SetPrimitiveType(nzPrimitiveType_TriangleList);
|
subMesh->SetPrimitiveMode(nzPrimitiveMode_TriangleList);
|
||||||
|
|
||||||
if (hasNormals && hasTexCoords)
|
if (hasNormals && hasTexCoords)
|
||||||
subMesh->GenerateTangents();
|
subMesh->GenerateTangents();
|
||||||
|
|
|
||||||
|
|
@ -3,6 +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
|
||||||
|
|
||||||
#include <Nazara/Graphics/Model.hpp>
|
#include <Nazara/Graphics/Model.hpp>
|
||||||
|
#include <Nazara/Graphics/AbstractRenderQueue.hpp>
|
||||||
#include <Nazara/Graphics/Config.hpp>
|
#include <Nazara/Graphics/Config.hpp>
|
||||||
#include <Nazara/Utility/SkeletalMesh.hpp>
|
#include <Nazara/Utility/SkeletalMesh.hpp>
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
#include <Nazara/Utility/StaticMesh.hpp>
|
||||||
|
|
@ -64,45 +65,9 @@ NzModel::~NzModel()
|
||||||
Reset();
|
Reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzModel::AddToRenderQueue(NzRenderQueue& renderQueue) const
|
void NzModel::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
|
||||||
{
|
{
|
||||||
if (!m_transformMatrixUpdated)
|
renderQueue->AddModel(this);
|
||||||
UpdateTransformMatrix();
|
|
||||||
|
|
||||||
unsigned int subMeshCount = m_mesh->GetSubMeshCount();
|
|
||||||
for (unsigned int i = 0; i < subMeshCount; ++i)
|
|
||||||
{
|
|
||||||
NzSubMesh* subMesh = m_mesh->GetSubMesh(i);
|
|
||||||
NzMaterial* material = m_materials[m_skin*m_matCount + subMesh->GetMaterialIndex()];
|
|
||||||
|
|
||||||
switch (subMesh->GetAnimationType())
|
|
||||||
{
|
|
||||||
case nzAnimationType_Skeletal:
|
|
||||||
{
|
|
||||||
NzSkeletalMesh* skeletalMesh = static_cast<NzSkeletalMesh*>(subMesh);
|
|
||||||
std::vector<NzRenderQueue::SkeletalData>& data = renderQueue.visibleSkeletalModels[material][skeletalMesh];
|
|
||||||
|
|
||||||
///TODO: Corriger cette abomination
|
|
||||||
data.resize(data.size()+1);
|
|
||||||
NzRenderQueue::SkeletalData& skeletalData = data.back();
|
|
||||||
|
|
||||||
skeletalData.skinnedVertices.resize(skeletalMesh->GetVertexCount());
|
|
||||||
skeletalData.transformMatrix = m_transformMatrix;
|
|
||||||
|
|
||||||
skeletalMesh->Skin(&skeletalData.skinnedVertices[0], &m_skeleton);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case nzAnimationType_Static:
|
|
||||||
{
|
|
||||||
NzStaticMesh* staticMesh = static_cast<NzStaticMesh*>(subMesh);
|
|
||||||
std::vector<NzMatrix4f>& matrices = renderQueue.visibleStaticModels[material][staticMesh];
|
|
||||||
|
|
||||||
matrices.push_back(m_transformMatrix);
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzModel::AdvanceAnimation(float elapsedTime)
|
void NzModel::AdvanceAnimation(float elapsedTime)
|
||||||
|
|
@ -310,6 +275,11 @@ bool NzModel::IsAnimationEnabled() const
|
||||||
return m_animationEnabled;
|
return m_animationEnabled;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool NzModel::IsDrawable() const
|
||||||
|
{
|
||||||
|
return m_mesh != nullptr && m_mesh->GetSubMeshCount() >= 1;
|
||||||
|
}
|
||||||
|
|
||||||
bool NzModel::IsDrawEnabled() const
|
bool NzModel::IsDrawEnabled() const
|
||||||
{
|
{
|
||||||
return m_drawEnabled;
|
return m_drawEnabled;
|
||||||
|
|
@ -702,9 +672,9 @@ void NzModel::UpdateBoundingBox() const
|
||||||
bool NzModel::VisibilityTest(const NzFrustumf& frustum)
|
bool NzModel::VisibilityTest(const NzFrustumf& frustum)
|
||||||
{
|
{
|
||||||
#if NAZARA_GRAPHICS_SAFE
|
#if NAZARA_GRAPHICS_SAFE
|
||||||
if (!m_mesh)
|
if (!IsDrawable())
|
||||||
{
|
{
|
||||||
NazaraError("Model has no mesh");
|
NazaraError("Model is not drawable");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -1,96 +0,0 @@
|
||||||
// Copyright (C) 2013 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/RenderQueue.hpp>
|
|
||||||
#include <Nazara/Renderer/Material.hpp>
|
|
||||||
#include <Nazara/Utility/SkeletalMesh.hpp>
|
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
|
||||||
|
|
||||||
bool NzRenderQueue::MaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2)
|
|
||||||
{
|
|
||||||
const NzShader* shader1 = mat1->GetCustomShader();
|
|
||||||
const NzShader* shader2 = mat2->GetCustomShader();
|
|
||||||
|
|
||||||
if (shader1)
|
|
||||||
{
|
|
||||||
if (shader2)
|
|
||||||
return shader1 < shader2;
|
|
||||||
else
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else if (shader2)
|
|
||||||
return false;
|
|
||||||
else
|
|
||||||
{
|
|
||||||
nzUInt32 shaderFlags1 = mat1->GetShaderFlags();
|
|
||||||
nzUInt32 shaderFlags2 = mat2->GetShaderFlags();
|
|
||||||
|
|
||||||
if (shaderFlags1 == shaderFlags2)
|
|
||||||
return mat1 < mat2;
|
|
||||||
else
|
|
||||||
return shaderFlags1 < shaderFlags2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NzRenderQueue::SkeletalMeshComparator::operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2)
|
|
||||||
{
|
|
||||||
const NzBuffer* buffer1;
|
|
||||||
const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer();
|
|
||||||
if (iBuffer1)
|
|
||||||
buffer1 = iBuffer1->GetBuffer();
|
|
||||||
else
|
|
||||||
buffer1 = nullptr;
|
|
||||||
|
|
||||||
const NzBuffer* buffer2;
|
|
||||||
const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer();
|
|
||||||
if (iBuffer2)
|
|
||||||
buffer2 = iBuffer1->GetBuffer();
|
|
||||||
else
|
|
||||||
buffer2 = nullptr;
|
|
||||||
|
|
||||||
if (buffer1 == buffer2)
|
|
||||||
return subMesh1 < subMesh2;
|
|
||||||
else
|
|
||||||
return buffer2 < buffer2;
|
|
||||||
}
|
|
||||||
|
|
||||||
bool NzRenderQueue::StaticMeshComparator::operator()(const NzStaticMesh* subMesh1, const NzStaticMesh* subMesh2)
|
|
||||||
{
|
|
||||||
const NzBuffer* buffer1;
|
|
||||||
const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer();
|
|
||||||
if (iBuffer1)
|
|
||||||
buffer1 = iBuffer1->GetBuffer();
|
|
||||||
else
|
|
||||||
buffer1 = nullptr;
|
|
||||||
|
|
||||||
const NzBuffer* buffer2;
|
|
||||||
const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer();
|
|
||||||
if (iBuffer2)
|
|
||||||
buffer2 = iBuffer1->GetBuffer();
|
|
||||||
else
|
|
||||||
buffer2 = nullptr;
|
|
||||||
|
|
||||||
if (iBuffer1 == iBuffer2)
|
|
||||||
{
|
|
||||||
buffer1 = subMesh1->GetVertexBuffer()->GetBuffer();
|
|
||||||
buffer2 = subMesh2->GetVertexBuffer()->GetBuffer();
|
|
||||||
|
|
||||||
if (buffer1 == buffer2)
|
|
||||||
return subMesh1 < subMesh2;
|
|
||||||
else
|
|
||||||
return buffer1 < buffer2;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
return iBuffer1 < iBuffer2;
|
|
||||||
}
|
|
||||||
|
|
||||||
void NzRenderQueue::Clear()
|
|
||||||
{
|
|
||||||
directionnalLights.clear();
|
|
||||||
otherDrawables.clear();
|
|
||||||
visibleLights.clear();
|
|
||||||
visibleSkeletalModels.clear();
|
|
||||||
visibleStaticModels.clear();
|
|
||||||
}
|
|
||||||
|
|
@ -5,41 +5,17 @@
|
||||||
#include <Nazara/Graphics/Scene.hpp>
|
#include <Nazara/Graphics/Scene.hpp>
|
||||||
#include <Nazara/Core/Clock.hpp>
|
#include <Nazara/Core/Clock.hpp>
|
||||||
#include <Nazara/Core/Error.hpp>
|
#include <Nazara/Core/Error.hpp>
|
||||||
#include <Nazara/Graphics/ColorBackground.hpp>
|
|
||||||
#include <Nazara/Graphics/Drawable.hpp>
|
|
||||||
#include <Nazara/Graphics/Camera.hpp>
|
#include <Nazara/Graphics/Camera.hpp>
|
||||||
#include <Nazara/Graphics/Light.hpp>
|
#include <Nazara/Graphics/ColorBackground.hpp>
|
||||||
#include <Nazara/Graphics/Model.hpp>
|
#include <Nazara/Graphics/ForwardRenderTechnique.hpp>
|
||||||
#include <Nazara/Graphics/RenderQueue.hpp>
|
|
||||||
#include <Nazara/Graphics/SceneRoot.hpp>
|
#include <Nazara/Graphics/SceneRoot.hpp>
|
||||||
#include <Nazara/Renderer/Config.hpp>
|
#include <Nazara/Renderer/Config.hpp>
|
||||||
#include <Nazara/Renderer/Renderer.hpp>
|
|
||||||
#include <Nazara/Renderer/Shader.hpp>
|
|
||||||
#include <Nazara/Renderer/ShaderBuilder.hpp>
|
|
||||||
#include <Nazara/Utility/BufferMapper.hpp>
|
|
||||||
#include <Nazara/Utility/SkeletalMesh.hpp>
|
|
||||||
#include <Nazara/Utility/StaticMesh.hpp>
|
|
||||||
#include <functional>
|
#include <functional>
|
||||||
#include <memory>
|
#include <memory>
|
||||||
#include <set>
|
#include <set>
|
||||||
#include <vector>
|
#include <vector>
|
||||||
#include <Nazara/Graphics/Debug.hpp>
|
#include <Nazara/Graphics/Debug.hpp>
|
||||||
|
|
||||||
namespace
|
|
||||||
{
|
|
||||||
const unsigned int maxLights = 8; ///TODO: Config
|
|
||||||
|
|
||||||
struct LightComparator
|
|
||||||
{
|
|
||||||
bool operator()(const NzLight* light1, const NzLight* light2)
|
|
||||||
{
|
|
||||||
return light1->GetPosition().SquaredDistance(pos) < light2->GetPosition().SquaredDistance(pos);
|
|
||||||
}
|
|
||||||
|
|
||||||
NzVector3f pos;
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
struct NzSceneImpl
|
struct NzSceneImpl
|
||||||
{
|
{
|
||||||
NzSceneImpl(NzScene* scene) :
|
NzSceneImpl(NzScene* scene) :
|
||||||
|
|
@ -47,16 +23,14 @@ struct NzSceneImpl
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
std::unique_ptr<NzAbstractRenderTechnique> renderTechnique;
|
||||||
std::unique_ptr<NzBackground> background;
|
std::unique_ptr<NzBackground> background;
|
||||||
std::vector<NzUpdatable*> updateList;
|
std::vector<NzUpdatable*> updateList;
|
||||||
std::vector<NzUpdatable*> visibleUpdateList;
|
std::vector<NzUpdatable*> visibleUpdateList;
|
||||||
std::vector<NzRenderer::InstancingData> instancingData;
|
|
||||||
NzClock updateClock;
|
NzClock updateClock;
|
||||||
NzColor ambientColor = NzColor(25,25,25);
|
NzColor ambientColor = NzColor(25,25,25);
|
||||||
NzRenderQueue renderQueue;
|
|
||||||
NzSceneRoot root;
|
NzSceneRoot root;
|
||||||
const NzCamera* activeCamera;
|
NzCamera* activeCamera;
|
||||||
NzVertexBuffer* skinningBuffer;
|
|
||||||
bool update;
|
bool update;
|
||||||
float frameTime;
|
float frameTime;
|
||||||
float updateTime;
|
float updateTime;
|
||||||
|
|
@ -67,10 +41,7 @@ NzScene::NzScene()
|
||||||
{
|
{
|
||||||
m_impl = new NzSceneImpl(this);
|
m_impl = new NzSceneImpl(this);
|
||||||
m_impl->background.reset(new NzColorBackground);
|
m_impl->background.reset(new NzColorBackground);
|
||||||
m_impl->skinningBuffer = new NzVertexBuffer(NzMesh::GetDeclaration(), 20000, nzBufferStorage_Hardware, nzBufferUsage_Dynamic);
|
m_impl->renderTechnique.reset(new NzForwardRenderTechnique);
|
||||||
|
|
||||||
if (NzRenderer::HasCapability(nzRendererCap_Instancing))
|
|
||||||
m_impl->instancingData.resize(NAZARA_RENDERER_INSTANCING_MAX);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
NzScene::~NzScene()
|
NzScene::~NzScene()
|
||||||
|
|
@ -81,7 +52,6 @@ NzScene::~NzScene()
|
||||||
static_cast<NzSceneNode*>(child)->SetScene(nullptr);
|
static_cast<NzSceneNode*>(child)->SetScene(nullptr);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete m_impl->skinningBuffer;
|
|
||||||
delete m_impl;
|
delete m_impl;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -92,11 +62,13 @@ void NzScene::AddToVisibilityList(NzUpdatable* object)
|
||||||
|
|
||||||
void NzScene::Cull()
|
void NzScene::Cull()
|
||||||
{
|
{
|
||||||
m_impl->renderQueue.Clear();
|
NzAbstractRenderQueue* renderQueue = m_impl->renderTechnique->GetRenderQueue();
|
||||||
|
renderQueue->Clear();
|
||||||
|
|
||||||
m_impl->visibleUpdateList.clear();
|
m_impl->visibleUpdateList.clear();
|
||||||
|
|
||||||
// Frustum culling
|
// Frustum culling
|
||||||
RecursiveFrustumCull(m_impl->renderQueue, m_impl->activeCamera->GetFrustum(), &m_impl->root);
|
RecursiveFrustumCull(renderQueue, m_impl->activeCamera->GetFrustum(), &m_impl->root);
|
||||||
|
|
||||||
///TODO: Occlusion culling
|
///TODO: Occlusion culling
|
||||||
|
|
||||||
|
|
@ -105,234 +77,30 @@ void NzScene::Cull()
|
||||||
|
|
||||||
void NzScene::Draw()
|
void NzScene::Draw()
|
||||||
{
|
{
|
||||||
NzRenderer::Clear(nzRendererClear_Depth);
|
m_impl->renderTechnique->Clear(this);
|
||||||
|
m_impl->renderTechnique->Draw(this);
|
||||||
if (m_impl->background)
|
|
||||||
m_impl->background->Draw(this);
|
|
||||||
|
|
||||||
LightComparator lightComparator;
|
|
||||||
|
|
||||||
// Pour les meshs squelettiques, on utilise un buffer commun
|
|
||||||
NzRenderer::SetVertexBuffer(m_impl->skinningBuffer);
|
|
||||||
for (auto matIt : m_impl->renderQueue.visibleSkeletalModels)
|
|
||||||
{
|
|
||||||
// On applique le shader du matériau
|
|
||||||
nzUInt32 shaderFlags = matIt.first->GetShaderFlags();
|
|
||||||
|
|
||||||
const NzShader* shader = NzShaderBuilder::Get(shaderFlags);
|
|
||||||
|
|
||||||
NzRenderer::SetShader(shader);
|
|
||||||
matIt.first->Apply(shader);
|
|
||||||
|
|
||||||
// Position de la caméra
|
|
||||||
int camPosLocation = shader->GetUniformLocation(nzShaderUniform_CameraPosition);
|
|
||||||
if (camPosLocation != -1)
|
|
||||||
shader->SendVector(camPosLocation, m_impl->activeCamera->GetPosition());
|
|
||||||
|
|
||||||
// Couleur ambiante de la scène
|
|
||||||
int sceneAmbientLocation = shader->GetUniformLocation(nzShaderUniform_SceneAmbient);
|
|
||||||
if (sceneAmbientLocation != -1)
|
|
||||||
shader->SendColor(sceneAmbientLocation, m_impl->ambientColor);
|
|
||||||
|
|
||||||
// Gestion des lumières (D'abord directionnelles)
|
|
||||||
int lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount);
|
|
||||||
|
|
||||||
unsigned int lightIndex = 0;
|
|
||||||
if (lightCountLocation != -1)
|
|
||||||
{
|
|
||||||
for (const NzLight* light : m_impl->renderQueue.directionnalLights)
|
|
||||||
{
|
|
||||||
light->Apply(shader, lightIndex++);
|
|
||||||
if (lightIndex > maxLights)
|
|
||||||
break; // N'arrivera jamais mais pourrait résulter en un bug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto subMeshIt : matIt.second)
|
|
||||||
{
|
|
||||||
const NzSkeletalMesh* skeletalMesh = subMeshIt.first;
|
|
||||||
const NzIndexBuffer* indexBuffer = skeletalMesh->GetIndexBuffer();
|
|
||||||
|
|
||||||
unsigned int vertexCount = skeletalMesh->GetVertexCount();
|
|
||||||
|
|
||||||
// Gestion du draw call avant la boucle de rendu
|
|
||||||
std::function<void(nzPrimitiveType, unsigned int, unsigned int)> drawFunc;
|
|
||||||
nzPrimitiveType primitiveType = skeletalMesh->GetPrimitiveType();
|
|
||||||
unsigned int indexCount;
|
|
||||||
if (indexBuffer)
|
|
||||||
{
|
|
||||||
drawFunc = NzRenderer::DrawIndexedPrimitives;
|
|
||||||
indexCount = indexBuffer->GetIndexCount();
|
|
||||||
NzRenderer::SetIndexBuffer(indexBuffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
drawFunc = NzRenderer::DrawPrimitives;
|
|
||||||
indexCount = skeletalMesh->GetVertexCount();
|
|
||||||
}
|
|
||||||
|
|
||||||
for (const NzRenderQueue::SkeletalData& data : subMeshIt.second)
|
|
||||||
{
|
|
||||||
// Transfert du résultat du skinning vers notre buffer hardware
|
|
||||||
NzBufferMapper<NzVertexBuffer> outputMapper(m_impl->skinningBuffer, nzBufferAccess_DiscardAndWrite, 0, vertexCount);
|
|
||||||
std::memcpy(outputMapper.GetPointer(), &data.skinnedVertices[0], vertexCount*sizeof(NzMeshVertex));
|
|
||||||
outputMapper.Unmap();
|
|
||||||
|
|
||||||
// Calcul des lumières les plus proches (TODO: LightManager ?)
|
|
||||||
if (lightCountLocation != -1)
|
|
||||||
{
|
|
||||||
auto visibleLights = m_impl->renderQueue.visibleLights;
|
|
||||||
lightComparator.pos = data.transformMatrix.GetTranslation();
|
|
||||||
std::sort(visibleLights.begin(), visibleLights.end(), lightComparator);
|
|
||||||
|
|
||||||
const unsigned int maxLightPerObject = 3; ///TODO: Config
|
|
||||||
unsigned int max = std::min(std::min(maxLights - lightIndex, maxLightPerObject), static_cast<unsigned int>(visibleLights.size()));
|
|
||||||
for (unsigned int i = 0; i < max; ++i)
|
|
||||||
visibleLights[i]->Apply(shader, lightIndex + i);
|
|
||||||
|
|
||||||
shader->SendInteger(lightCountLocation, lightIndex + max);
|
|
||||||
}
|
|
||||||
|
|
||||||
NzRenderer::SetMatrix(nzMatrixType_World, data.transformMatrix);
|
|
||||||
|
|
||||||
drawFunc(primitiveType, 0, indexCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Pour les meshs statiques, on utilise le buffer du mesh
|
|
||||||
for (auto matIt : m_impl->renderQueue.visibleStaticModels)
|
|
||||||
{
|
|
||||||
// On applique le shader du matériau
|
|
||||||
nzUInt32 shaderFlags = matIt.first->GetShaderFlags();
|
|
||||||
if (NzRenderer::HasCapability(nzRendererCap_Instancing) && m_impl->renderQueue.visibleLights.empty())
|
|
||||||
shaderFlags |= nzShaderFlags_Instancing;
|
|
||||||
|
|
||||||
const NzShader* shader = NzShaderBuilder::Get(shaderFlags);
|
|
||||||
|
|
||||||
NzRenderer::SetShader(shader);
|
|
||||||
matIt.first->Apply(shader);
|
|
||||||
|
|
||||||
bool instancing = shader->GetFlags() & nzShaderFlags_Instancing;
|
|
||||||
|
|
||||||
// Position de la caméra
|
|
||||||
int camPosLocation = shader->GetUniformLocation(nzShaderUniform_CameraPosition);
|
|
||||||
if (camPosLocation != -1)
|
|
||||||
shader->SendVector(camPosLocation, m_impl->activeCamera->GetPosition());
|
|
||||||
|
|
||||||
// Couleur ambiante de la scène
|
|
||||||
int sceneAmbientLocation = shader->GetUniformLocation(nzShaderUniform_SceneAmbient);
|
|
||||||
if (sceneAmbientLocation != -1)
|
|
||||||
shader->SendColor(sceneAmbientLocation, m_impl->ambientColor);
|
|
||||||
|
|
||||||
// Gestion des lumières (D'abord directionnelles)
|
|
||||||
int lightCountLocation = shader->GetUniformLocation(nzShaderUniform_LightCount);
|
|
||||||
|
|
||||||
unsigned int lightIndex = 0;
|
|
||||||
if (lightCountLocation != -1)
|
|
||||||
{
|
|
||||||
for (const NzLight* light : m_impl->renderQueue.directionnalLights)
|
|
||||||
{
|
|
||||||
light->Apply(shader, lightIndex++);
|
|
||||||
if (lightIndex > maxLights)
|
|
||||||
break; // N'arrivera probablement jamais mais pourrait résulter en un bug
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (auto subMeshIt : matIt.second)
|
|
||||||
{
|
|
||||||
NzStaticMesh* staticMesh = subMeshIt.first;
|
|
||||||
|
|
||||||
const NzIndexBuffer* indexBuffer = staticMesh->GetIndexBuffer();
|
|
||||||
const NzVertexBuffer* vertexBuffer = staticMesh->GetVertexBuffer();
|
|
||||||
|
|
||||||
NzRenderer::SetVertexBuffer(vertexBuffer);
|
|
||||||
|
|
||||||
// Gestion du draw call avant la boucle de rendu
|
|
||||||
std::function<void(nzPrimitiveType, unsigned int, unsigned int)> draw;
|
|
||||||
std::function<void(unsigned int, nzPrimitiveType, unsigned int, unsigned int)> instancedDraw;
|
|
||||||
nzPrimitiveType primitiveType = staticMesh->GetPrimitiveType();
|
|
||||||
unsigned int indexCount;
|
|
||||||
if (indexBuffer)
|
|
||||||
{
|
|
||||||
draw = NzRenderer::DrawIndexedPrimitives;
|
|
||||||
indexCount = indexBuffer->GetIndexCount();
|
|
||||||
instancedDraw = NzRenderer::DrawIndexedPrimitivesInstanced;
|
|
||||||
NzRenderer::SetIndexBuffer(indexBuffer);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
draw = NzRenderer::DrawPrimitives;
|
|
||||||
indexCount = vertexBuffer->GetVertexCount();
|
|
||||||
instancedDraw = NzRenderer::DrawPrimitivesInstanced;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (instancing)
|
|
||||||
{
|
|
||||||
if (lightCountLocation != -1)
|
|
||||||
shader->SendInteger(lightCountLocation, lightIndex);
|
|
||||||
|
|
||||||
unsigned int count = 0;
|
|
||||||
for (const NzMatrix4f& matrix : subMeshIt.second)
|
|
||||||
{
|
|
||||||
m_impl->instancingData[count++].worldMatrix = matrix;
|
|
||||||
if (count == m_impl->instancingData.size())
|
|
||||||
{
|
|
||||||
NzRenderer::SetInstancingData(&m_impl->instancingData[0], count);
|
|
||||||
instancedDraw(count, primitiveType, 0, indexCount);
|
|
||||||
|
|
||||||
count = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (count > 0)
|
|
||||||
{
|
|
||||||
NzRenderer::SetInstancingData(&m_impl->instancingData[0], count);
|
|
||||||
instancedDraw(count, primitiveType, 0, indexCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
for (const NzMatrix4f& matrix : subMeshIt.second)
|
|
||||||
{
|
|
||||||
// Calcul des lumières les plus proches (TODO: LightManager ?)
|
|
||||||
if (lightCountLocation != -1)
|
|
||||||
{
|
|
||||||
std::vector<const NzLight*>& visibleLights = m_impl->renderQueue.visibleLights;
|
|
||||||
lightComparator.pos = matrix.GetTranslation();
|
|
||||||
std::sort(visibleLights.begin(), visibleLights.end(), lightComparator);
|
|
||||||
|
|
||||||
const unsigned int maxLightPerObject = 3; ///TODO: Config
|
|
||||||
unsigned int max = std::min(std::min(maxLights - lightIndex, maxLightPerObject), static_cast<unsigned int>(visibleLights.size()));
|
|
||||||
for (unsigned int i = 0; i < max; ++i)
|
|
||||||
visibleLights[i]->Apply(shader, lightIndex + i);
|
|
||||||
|
|
||||||
shader->SendInteger(lightCountLocation, lightIndex + max);
|
|
||||||
}
|
|
||||||
|
|
||||||
NzRenderer::SetMatrix(nzMatrixType_World, matrix);
|
|
||||||
|
|
||||||
draw(primitiveType, 0, indexCount);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Les autres drawables (Exemple: Terrain)
|
|
||||||
for (const NzDrawable* drawable : m_impl->renderQueue.otherDrawables)
|
|
||||||
drawable->Draw();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
const NzCamera* NzScene::GetActiveCamera() const
|
NzCamera* NzScene::GetActiveCamera() const
|
||||||
{
|
{
|
||||||
return m_impl->activeCamera;
|
return m_impl->activeCamera;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NzColor NzScene::GetAmbientColor() const
|
||||||
|
{
|
||||||
|
return m_impl->ambientColor;
|
||||||
|
}
|
||||||
|
|
||||||
NzBackground* NzScene::GetBackground() const
|
NzBackground* NzScene::GetBackground() const
|
||||||
{
|
{
|
||||||
return m_impl->background.get();
|
return m_impl->background.get();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
NzAbstractRenderTechnique* NzScene::GetRenderTechnique() const
|
||||||
|
{
|
||||||
|
return m_impl->renderTechnique.get();
|
||||||
|
}
|
||||||
|
|
||||||
NzSceneNode& NzScene::GetRoot() const
|
NzSceneNode& NzScene::GetRoot() const
|
||||||
{
|
{
|
||||||
return m_impl->root;
|
return m_impl->root;
|
||||||
|
|
@ -371,6 +139,11 @@ void NzScene::SetBackground(NzBackground* background)
|
||||||
m_impl->background.reset(background);
|
m_impl->background.reset(background);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void NzScene::SetRenderTechnique(NzAbstractRenderTechnique* renderTechnique)
|
||||||
|
{
|
||||||
|
m_impl->renderTechnique.reset(renderTechnique);
|
||||||
|
}
|
||||||
|
|
||||||
void NzScene::SetUpdatePerSecond(unsigned int updatePerSecond)
|
void NzScene::SetUpdatePerSecond(unsigned int updatePerSecond)
|
||||||
{
|
{
|
||||||
m_impl->updatePerSecond = updatePerSecond;
|
m_impl->updatePerSecond = updatePerSecond;
|
||||||
|
|
@ -419,7 +192,7 @@ NzScene::operator const NzSceneNode&() const
|
||||||
return m_impl->root;
|
return m_impl->root;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzScene::RecursiveFrustumCull(NzRenderQueue& 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())
|
||||||
{
|
{
|
||||||
|
|
@ -437,7 +210,7 @@ void NzScene::RecursiveFrustumCull(NzRenderQueue& renderQueue, const NzFrustumf&
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzScene::SetActiveCamera(const NzCamera* camera)
|
void NzScene::SetActiveCamera(NzCamera* camera)
|
||||||
{
|
{
|
||||||
m_impl->activeCamera = camera;
|
m_impl->activeCamera = camera;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -13,7 +13,7 @@ NzSceneRoot::NzSceneRoot(NzScene* scene)
|
||||||
|
|
||||||
NzSceneRoot::~NzSceneRoot() = default;
|
NzSceneRoot::~NzSceneRoot() = default;
|
||||||
|
|
||||||
void NzSceneRoot::AddToRenderQueue(NzRenderQueue& renderQueue) const
|
void NzSceneRoot::AddToRenderQueue(NzAbstractRenderQueue* renderQueue) const
|
||||||
{
|
{
|
||||||
NazaraUnused(renderQueue);
|
NazaraUnused(renderQueue);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -224,7 +224,7 @@ void NzSkyboxBackground::Draw(const NzScene* scene) const
|
||||||
NzRenderer::SetTextureSampler(textureUnit, m_sampler);
|
NzRenderer::SetTextureSampler(textureUnit, m_sampler);
|
||||||
NzRenderer::SetVertexBuffer(m_vertexBuffer);
|
NzRenderer::SetVertexBuffer(m_vertexBuffer);
|
||||||
|
|
||||||
NzRenderer::DrawIndexedPrimitives(nzPrimitiveType_TriangleList, 0, 36);
|
NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode_TriangleList, 0, 36);
|
||||||
|
|
||||||
NzRenderer::SetMatrix(nzMatrixType_View, viewMatrix);
|
NzRenderer::SetMatrix(nzMatrixType_View, viewMatrix);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -135,7 +135,7 @@ void NzDebugDrawer::Draw(const NzCubef& cube)
|
||||||
|
|
||||||
shader->SendColor(colorLocation, primaryColor);
|
shader->SendColor(colorLocation, primaryColor);
|
||||||
|
|
||||||
NzRenderer::DrawPrimitives(nzPrimitiveType_LineList, 0, 24);
|
NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzDebugDrawer::Draw(const NzCubeui& cube)
|
void NzDebugDrawer::Draw(const NzCubeui& cube)
|
||||||
|
|
@ -223,7 +223,7 @@ void NzDebugDrawer::Draw(const NzFrustumf& frustum)
|
||||||
|
|
||||||
shader->SendColor(colorLocation, primaryColor);
|
shader->SendColor(colorLocation, primaryColor);
|
||||||
|
|
||||||
NzRenderer::DrawPrimitives(nzPrimitiveType_LineList, 0, 24);
|
NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube)
|
void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube)
|
||||||
|
|
@ -306,7 +306,7 @@ void NzDebugDrawer::Draw(const NzOrientedCubef& orientedCube)
|
||||||
|
|
||||||
shader->SendColor(colorLocation, primaryColor);
|
shader->SendColor(colorLocation, primaryColor);
|
||||||
|
|
||||||
NzRenderer::DrawPrimitives(nzPrimitiveType_LineList, 0, 24);
|
NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, 24);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
|
void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
|
||||||
|
|
@ -355,10 +355,10 @@ void NzDebugDrawer::Draw(const NzSkeleton* skeleton)
|
||||||
NzRenderer::SetVertexBuffer(vertexBuffer);
|
NzRenderer::SetVertexBuffer(vertexBuffer);
|
||||||
|
|
||||||
shader->SendColor(colorLocation, primaryColor);
|
shader->SendColor(colorLocation, primaryColor);
|
||||||
NzRenderer::DrawPrimitives(nzPrimitiveType_LineList, 0, vertexCount);
|
NzRenderer::DrawPrimitives(nzPrimitiveMode_LineList, 0, vertexCount);
|
||||||
|
|
||||||
shader->SendColor(colorLocation, secondaryColor);
|
shader->SendColor(colorLocation, secondaryColor);
|
||||||
NzRenderer::DrawPrimitives(nzPrimitiveType_PointList, 0, vertexCount);
|
NzRenderer::DrawPrimitives(nzPrimitiveMode_PointList, 0, vertexCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
/*
|
/*
|
||||||
|
|
|
||||||
|
|
@ -1010,14 +1010,14 @@ GLenum NzOpenGL::FaceFilling[nzFaceFilling_Max+1] =
|
||||||
GL_FILL // nzFaceFilling_Fill
|
GL_FILL // nzFaceFilling_Fill
|
||||||
};
|
};
|
||||||
|
|
||||||
GLenum NzOpenGL::PrimitiveType[nzPrimitiveType_Max+1] =
|
GLenum NzOpenGL::PrimitiveMode[nzPrimitiveMode_Max+1] =
|
||||||
{
|
{
|
||||||
GL_LINES, // nzPrimitiveType_LineList,
|
GL_LINES, // nzPrimitiveMode_LineList
|
||||||
GL_LINE_STRIP, // nzPrimitiveType_LineStrip,
|
GL_LINE_STRIP, // nzPrimitiveMode_LineStrip
|
||||||
GL_POINTS, // nzPrimitiveType_PointList,
|
GL_POINTS, // nzPrimitiveMode_PointList
|
||||||
GL_TRIANGLES, // nzPrimitiveType_TriangleList,
|
GL_TRIANGLES, // nzPrimitiveMode_TriangleList
|
||||||
GL_TRIANGLE_STRIP, // nzPrimitiveType_TriangleStrip,
|
GL_TRIANGLE_STRIP, // nzPrimitiveMode_TriangleStrip
|
||||||
GL_TRIANGLE_FAN // nzPrimitiveType_TriangleFan
|
GL_TRIANGLE_FAN // nzPrimitiveMode_TriangleFan
|
||||||
};
|
};
|
||||||
|
|
||||||
GLenum NzOpenGL::RendererComparison[nzRendererComparison_Max+1] =
|
GLenum NzOpenGL::RendererComparison[nzRendererComparison_Max+1] =
|
||||||
|
|
|
||||||
|
|
@ -133,7 +133,7 @@ void NzRenderer::Clear(unsigned long flags)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount)
|
void NzRenderer::DrawIndexedPrimitives(nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (NzContext::GetCurrent() == nullptr)
|
if (NzContext::GetCurrent() == nullptr)
|
||||||
|
|
@ -142,9 +142,9 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primitive > nzPrimitiveType_Max)
|
if (mode > nzPrimitiveMode_Max)
|
||||||
{
|
{
|
||||||
NazaraError("Primitive type out of enum");
|
NazaraError("Primitive mode out of enum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -166,7 +166,7 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_indexBuffer->IsSequential())
|
if (s_indexBuffer->IsSequential())
|
||||||
glDrawArrays(NzOpenGL::PrimitiveType[primitive], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount());
|
glDrawArrays(NzOpenGL::PrimitiveMode[mode], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount());
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GLenum type;
|
GLenum type;
|
||||||
|
|
@ -182,11 +182,11 @@ void NzRenderer::DrawIndexedPrimitives(nzPrimitiveType primitive, unsigned int f
|
||||||
type = GL_UNSIGNED_SHORT;
|
type = GL_UNSIGNED_SHORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawElements(NzOpenGL::PrimitiveType[primitive], indexCount, type, ptr);
|
glDrawElements(NzOpenGL::PrimitiveMode[mode], indexCount, type, ptr);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, unsigned int firstIndex, unsigned int indexCount)
|
void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstIndex, unsigned int indexCount)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (NzContext::GetCurrent() == nullptr)
|
if (NzContext::GetCurrent() == nullptr)
|
||||||
|
|
@ -195,9 +195,9 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primitive > nzPrimitiveType_Max)
|
if (mode > nzPrimitiveMode_Max)
|
||||||
{
|
{
|
||||||
NazaraError("Primitive type out of enum");
|
NazaraError("Primitive mode out of enum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -221,9 +221,9 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceCount > NAZARA_RENDERER_INSTANCING_MAX)
|
if (instanceCount > NAZARA_RENDERER_MAX_INSTANCES)
|
||||||
{
|
{
|
||||||
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " + NzString::Number(NAZARA_RENDERER_INSTANCING_MAX) + ')');
|
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -237,7 +237,7 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
|
||||||
}
|
}
|
||||||
|
|
||||||
if (s_indexBuffer->IsSequential())
|
if (s_indexBuffer->IsSequential())
|
||||||
glDrawArraysInstanced(NzOpenGL::PrimitiveType[primitive], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount(), instanceCount);
|
glDrawArraysInstanced(NzOpenGL::PrimitiveMode[mode], s_indexBuffer->GetStartIndex(), s_indexBuffer->GetIndexCount(), instanceCount);
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
GLenum type;
|
GLenum type;
|
||||||
|
|
@ -253,11 +253,11 @@ void NzRenderer::DrawIndexedPrimitivesInstanced(unsigned int instanceCount, nzPr
|
||||||
type = GL_UNSIGNED_SHORT;
|
type = GL_UNSIGNED_SHORT;
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawElementsInstanced(NzOpenGL::PrimitiveType[primitive], indexCount, type, ptr, instanceCount);
|
glDrawElementsInstanced(NzOpenGL::PrimitiveMode[mode], indexCount, type, ptr, instanceCount);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount)
|
void NzRenderer::DrawPrimitives(nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (NzContext::GetCurrent() == nullptr)
|
if (NzContext::GetCurrent() == nullptr)
|
||||||
|
|
@ -266,9 +266,9 @@ void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primitive > nzPrimitiveType_Max)
|
if (mode > nzPrimitiveMode_Max)
|
||||||
{
|
{
|
||||||
NazaraError("Primitive type out of enum");
|
NazaraError("Primitive mode out of enum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -281,10 +281,10 @@ void NzRenderer::DrawPrimitives(nzPrimitiveType primitive, unsigned int firstVer
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawArrays(NzOpenGL::PrimitiveType[primitive], firstVertex, vertexCount);
|
glDrawArrays(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveType primitive, unsigned int firstVertex, unsigned int vertexCount)
|
void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitiveMode mode, unsigned int firstVertex, unsigned int vertexCount)
|
||||||
{
|
{
|
||||||
#ifdef NAZARA_DEBUG
|
#ifdef NAZARA_DEBUG
|
||||||
if (NzContext::GetCurrent() == nullptr)
|
if (NzContext::GetCurrent() == nullptr)
|
||||||
|
|
@ -293,9 +293,9 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (primitive > nzPrimitiveType_Max)
|
if (mode > nzPrimitiveMode_Max)
|
||||||
{
|
{
|
||||||
NazaraError("Primitive type out of enum");
|
NazaraError("Primitive mode out of enum");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -313,9 +313,9 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceCount > NAZARA_RENDERER_INSTANCING_MAX)
|
if (instanceCount > NAZARA_RENDERER_MAX_INSTANCES)
|
||||||
{
|
{
|
||||||
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " + NzString::Number(NAZARA_RENDERER_INSTANCING_MAX) + ')');
|
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")" );
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
@ -328,7 +328,7 @@ void NzRenderer::DrawPrimitivesInstanced(unsigned int instanceCount, nzPrimitive
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
glDrawArraysInstanced(NzOpenGL::PrimitiveType[primitive], firstVertex, vertexCount, instanceCount);
|
glDrawArraysInstanced(NzOpenGL::PrimitiveMode[mode], firstVertex, vertexCount, instanceCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVector2f& uv0, const NzVector2f& uv1, float z)
|
void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVector2f& uv0, const NzVector2f& uv1, float z)
|
||||||
|
|
@ -443,7 +443,7 @@ void NzRenderer::DrawTexture(unsigned int unit, const NzRectf& rect, const NzVec
|
||||||
|
|
||||||
shader->SendMatrix(s_matrixLocation[nzMatrixCombination_WorldViewProj], NzMatrix4f::Ortho(0.f, s_targetSize.x, 0.f, s_targetSize.y, 0.f));
|
shader->SendMatrix(s_matrixLocation[nzMatrixCombination_WorldViewProj], NzMatrix4f::Ortho(0.f, s_targetSize.x, 0.f, s_targetSize.y, 0.f));
|
||||||
|
|
||||||
glDrawArrays(NzOpenGL::PrimitiveType[nzPrimitiveType_TriangleStrip], 0, 4);
|
glDrawArrays(NzOpenGL::PrimitiveMode[nzPrimitiveMode_TriangleStrip], 0, 4);
|
||||||
|
|
||||||
// Restauration
|
// Restauration
|
||||||
Enable(nzRendererParameter_FaceCulling, faceCulling);
|
Enable(nzRendererParameter_FaceCulling, faceCulling);
|
||||||
|
|
@ -706,7 +706,7 @@ bool NzRenderer::Initialize()
|
||||||
if (s_capabilities[nzRendererCap_Instancing])
|
if (s_capabilities[nzRendererCap_Instancing])
|
||||||
{
|
{
|
||||||
s_instancingBuffer = new NzBuffer(nzBufferType_Vertex);
|
s_instancingBuffer = new NzBuffer(nzBufferType_Vertex);
|
||||||
if (!s_instancingBuffer->Create(NAZARA_RENDERER_INSTANCING_MAX, sizeof(InstancingData), nzBufferStorage_Hardware, nzBufferUsage_Dynamic))
|
if (!s_instancingBuffer->Create(NAZARA_RENDERER_MAX_INSTANCES, sizeof(InstancingData), nzBufferStorage_Hardware, nzBufferUsage_Dynamic))
|
||||||
{
|
{
|
||||||
s_capabilities[nzRendererCap_Instancing] = false;
|
s_capabilities[nzRendererCap_Instancing] = false;
|
||||||
|
|
||||||
|
|
@ -1014,9 +1014,9 @@ void NzRenderer::SetInstancingData(const NzRenderer::InstancingData* instancingD
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (instanceCount > NAZARA_RENDERER_INSTANCING_MAX)
|
if (instanceCount > NAZARA_RENDERER_MAX_INSTANCES)
|
||||||
{
|
{
|
||||||
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " + NzString::Number(NAZARA_RENDERER_INSTANCING_MAX) + ')');
|
NazaraError("Instance count is over maximum instance count (" + NzString::Number(instanceCount) + " >= " NazaraStringifyMacro(NAZARA_RENDERER_MAX_INSTANCES) ")");
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
|
||||||
|
|
@ -44,7 +44,6 @@ namespace
|
||||||
sourceCode += "#define LIGHT_DIRECTIONAL 0\n"
|
sourceCode += "#define LIGHT_DIRECTIONAL 0\n"
|
||||||
"#define LIGHT_POINT 1\n"
|
"#define LIGHT_POINT 1\n"
|
||||||
"#define LIGHT_SPOT 2\n"
|
"#define LIGHT_SPOT 2\n"
|
||||||
"#define MAX_LIGHTS 8\n"
|
|
||||||
"\n";
|
"\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -71,7 +70,7 @@ namespace
|
||||||
{
|
{
|
||||||
sourceCode += "uniform vec3 CameraPosition;\n"
|
sourceCode += "uniform vec3 CameraPosition;\n"
|
||||||
"uniform int LightCount;\n"
|
"uniform int LightCount;\n"
|
||||||
"uniform Light Lights[MAX_LIGHTS];\n"
|
"uniform Light Lights[" NazaraStringifyMacro(NAZARA_RENDERER_SHADER_MAX_LIGHTCOUNT) "];\n"
|
||||||
"uniform vec4 MaterialAmbient;\n";
|
"uniform vec4 MaterialAmbient;\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -290,8 +289,9 @@ namespace
|
||||||
|
|
||||||
if (flags & nzShaderFlags_EmissiveMapping)
|
if (flags & nzShaderFlags_EmissiveMapping)
|
||||||
{
|
{
|
||||||
sourceCode += "vec3 emission = vec3(" + textureLookupKW + "(MaterialEmissiveMap, vTexCoord));\n"
|
sourceCode += "float intensity = light.r*0.3 + light.g*0.59 + light.b*0.11;\n"
|
||||||
+ fragmentColorKW + " = vec4(mix(lighting, emission, max(0.0, 1.0-length(light))), alpha);\n";
|
"vec3 emission = vec3(" + textureLookupKW + "(MaterialEmissiveMap, vTexCoord));\n"
|
||||||
|
+ fragmentColorKW + " = vec4(mix(lighting, emission, clamp(1.0 - 3.0*intensity, 0.0, 1.0)), alpha);\n";
|
||||||
///NOTE: Pour un shader avec un coût réduit avec une qualité moyenne, il est possible de remplacer "length(light)" par "dot(light, light)"
|
///NOTE: Pour un shader avec un coût réduit avec une qualité moyenne, il est possible de remplacer "length(light)" par "dot(light, light)"
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -53,56 +53,18 @@ namespace
|
||||||
|
|
||||||
bool Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters)
|
bool Load(NzImage* image, NzInputStream& stream, const NzImageParams& parameters)
|
||||||
{
|
{
|
||||||
static const nzPixelFormat formats[4] =
|
// Je charge tout en RGBA8 et je converti ensuite via la méthode Convert
|
||||||
{
|
// Ceci à cause d'un bug de STB lorsqu'il s'agit de charger certaines images (ex: JPG) en "default"
|
||||||
nzPixelFormat_L8,
|
|
||||||
nzPixelFormat_LA8,
|
|
||||||
nzPixelFormat_RGB8,
|
|
||||||
nzPixelFormat_RGBA8
|
|
||||||
};
|
|
||||||
|
|
||||||
nzPixelFormat format;
|
|
||||||
int stbiFormat;
|
|
||||||
switch (parameters.loadFormat)
|
|
||||||
{
|
|
||||||
case nzPixelFormat_L8:
|
|
||||||
format = nzPixelFormat_L8;
|
|
||||||
stbiFormat = STBI_grey;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case nzPixelFormat_LA8:
|
|
||||||
format = nzPixelFormat_LA8;
|
|
||||||
stbiFormat = STBI_grey_alpha;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case nzPixelFormat_RGB8:
|
|
||||||
format = nzPixelFormat_RGB8;
|
|
||||||
stbiFormat = STBI_rgb;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case nzPixelFormat_RGBA8:
|
|
||||||
format = nzPixelFormat_RGBA8;
|
|
||||||
stbiFormat = STBI_rgb_alpha;
|
|
||||||
break;
|
|
||||||
|
|
||||||
default:
|
|
||||||
format = nzPixelFormat_Undefined;
|
|
||||||
stbiFormat = STBI_default;
|
|
||||||
}
|
|
||||||
|
|
||||||
int width, height, bpp;
|
int width, height, bpp;
|
||||||
nzUInt8* ptr = stbi_load_from_callbacks(&callbacks, &stream, &width, &height, &bpp, stbiFormat);
|
nzUInt8* ptr = stbi_load_from_callbacks(&callbacks, &stream, &width, &height, &bpp, STBI_rgb_alpha);
|
||||||
|
|
||||||
if (!ptr)
|
if (!ptr)
|
||||||
{
|
{
|
||||||
NazaraError("Failed to load image: " + NzString(stbi_failure_reason()));
|
NazaraError("Failed to load image: " + NzString(stbi_failure_reason()));
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (format == nzPixelFormat_Undefined)
|
if (!image->Create(nzImageType_2D, nzPixelFormat_RGBA8, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
||||||
format = formats[bpp-1];
|
|
||||||
|
|
||||||
if (!image->Create(nzImageType_2D, format, width, height, 1, (parameters.levelCount > 0) ? parameters.levelCount : 1))
|
|
||||||
{
|
{
|
||||||
NazaraError("Failed to create image");
|
NazaraError("Failed to create image");
|
||||||
stbi_image_free(ptr);
|
stbi_image_free(ptr);
|
||||||
|
|
@ -111,10 +73,9 @@ namespace
|
||||||
}
|
}
|
||||||
|
|
||||||
image->Update(ptr);
|
image->Update(ptr);
|
||||||
|
|
||||||
stbi_image_free(ptr);
|
stbi_image_free(ptr);
|
||||||
|
|
||||||
if (stbiFormat == STBI_default && parameters.loadFormat != nzPixelFormat_Undefined)
|
if (parameters.loadFormat != nzPixelFormat_Undefined)
|
||||||
image->Convert(parameters.loadFormat);
|
image->Convert(parameters.loadFormat);
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
|
|
|
||||||
|
|
@ -14,7 +14,7 @@
|
||||||
|
|
||||||
NzSubMesh::NzSubMesh(const NzMesh* parent) :
|
NzSubMesh::NzSubMesh(const NzMesh* parent) :
|
||||||
NzResource(false), // Un SubMesh n'est pas persistant par défaut
|
NzResource(false), // Un SubMesh n'est pas persistant par défaut
|
||||||
m_primitiveType(nzPrimitiveType_TriangleList),
|
m_primitiveMode(nzPrimitiveMode_TriangleList),
|
||||||
m_parent(parent),
|
m_parent(parent),
|
||||||
m_matIndex(0)
|
m_matIndex(0)
|
||||||
{
|
{
|
||||||
|
|
@ -147,9 +147,9 @@ const NzMesh* NzSubMesh::GetParent() const
|
||||||
return m_parent;
|
return m_parent;
|
||||||
}
|
}
|
||||||
|
|
||||||
nzPrimitiveType NzSubMesh::GetPrimitiveType() const
|
nzPrimitiveMode NzSubMesh::GetPrimitiveMode() const
|
||||||
{
|
{
|
||||||
return m_primitiveType;
|
return m_primitiveMode;
|
||||||
}
|
}
|
||||||
|
|
||||||
unsigned int NzSubMesh::GetTriangleCount() const
|
unsigned int NzSubMesh::GetTriangleCount() const
|
||||||
|
|
@ -161,24 +161,24 @@ unsigned int NzSubMesh::GetTriangleCount() const
|
||||||
else
|
else
|
||||||
indexCount = GetVertexCount();
|
indexCount = GetVertexCount();
|
||||||
|
|
||||||
switch (m_primitiveType)
|
switch (m_primitiveMode)
|
||||||
{
|
{
|
||||||
case nzPrimitiveType_LineList:
|
case nzPrimitiveMode_LineList:
|
||||||
case nzPrimitiveType_LineStrip:
|
case nzPrimitiveMode_LineStrip:
|
||||||
case nzPrimitiveType_PointList:
|
case nzPrimitiveMode_PointList:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case nzPrimitiveType_TriangleFan:
|
case nzPrimitiveMode_TriangleFan:
|
||||||
return (indexCount - 1) / 2;
|
return (indexCount - 1) / 2;
|
||||||
|
|
||||||
case nzPrimitiveType_TriangleList:
|
case nzPrimitiveMode_TriangleList:
|
||||||
return indexCount / 3;
|
return indexCount / 3;
|
||||||
|
|
||||||
case nzPrimitiveType_TriangleStrip:
|
case nzPrimitiveMode_TriangleStrip:
|
||||||
return indexCount - 2;
|
return indexCount - 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
NazaraError("Primitive type not handled (0x" + NzString::Number(m_primitiveType, 16) + ')');
|
NazaraError("Primitive mode not handled (0x" + NzString::Number(m_primitiveMode, 16) + ')');
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -187,9 +187,9 @@ unsigned int NzSubMesh::GetMaterialIndex() const
|
||||||
return m_matIndex;
|
return m_matIndex;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzSubMesh::SetPrimitiveType(nzPrimitiveType primitiveType)
|
void NzSubMesh::SetPrimitiveMode(nzPrimitiveMode mode)
|
||||||
{
|
{
|
||||||
m_primitiveType = primitiveType;
|
m_primitiveMode = mode;
|
||||||
}
|
}
|
||||||
|
|
||||||
void NzSubMesh::SetMaterialIndex(unsigned int matIndex)
|
void NzSubMesh::SetMaterialIndex(unsigned int matIndex)
|
||||||
|
|
|
||||||
|
|
@ -7,7 +7,7 @@
|
||||||
#include <Nazara/Utility/Debug.hpp>
|
#include <Nazara/Utility/Debug.hpp>
|
||||||
|
|
||||||
NzTriangleIterator::NzTriangleIterator(NzSubMesh* subMesh, nzBufferAccess access) :
|
NzTriangleIterator::NzTriangleIterator(NzSubMesh* subMesh, nzBufferAccess access) :
|
||||||
m_primitiveType(subMesh->GetPrimitiveType()),
|
m_primitiveMode(subMesh->GetPrimitiveMode()),
|
||||||
m_indexMapper(subMesh->GetIndexBuffer(), nzBufferAccess_ReadOnly),
|
m_indexMapper(subMesh->GetIndexBuffer(), nzBufferAccess_ReadOnly),
|
||||||
m_vertexMapper(subMesh)
|
m_vertexMapper(subMesh)
|
||||||
{
|
{
|
||||||
|
|
@ -33,20 +33,20 @@ bool NzTriangleIterator::Advance()
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
switch (m_primitiveType)
|
switch (m_primitiveMode)
|
||||||
{
|
{
|
||||||
case nzPrimitiveType_TriangleFan:
|
case nzPrimitiveMode_TriangleFan:
|
||||||
m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++);
|
m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++);
|
||||||
m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++);
|
m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nzPrimitiveType_TriangleList:
|
case nzPrimitiveMode_TriangleList:
|
||||||
m_triangleIndices[0] = m_indexMapper.Get(m_currentIndex++);
|
m_triangleIndices[0] = m_indexMapper.Get(m_currentIndex++);
|
||||||
m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++);
|
m_triangleIndices[1] = m_indexMapper.Get(m_currentIndex++);
|
||||||
m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++);
|
m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case nzPrimitiveType_TriangleStrip:
|
case nzPrimitiveMode_TriangleStrip:
|
||||||
m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++);
|
m_triangleIndices[2] = m_indexMapper.Get(m_currentIndex++);
|
||||||
m_triangleIndices[1] = m_triangleIndices[2];
|
m_triangleIndices[1] = m_triangleIndices[2];
|
||||||
m_triangleIndices[0] = m_triangleIndices[1];
|
m_triangleIndices[0] = m_triangleIndices[1];
|
||||||
|
|
|
||||||
Loading…
Reference in New Issue