Fixed repo

Former-commit-id: 5992da5ec759f05dabf82009e660ec58eed96365
This commit is contained in:
Lynix
2012-11-29 10:15:10 +01:00
parent 0a2e19fa22
commit a2eb55e74a
14 changed files with 692 additions and 23 deletions

399
src/Nazara/3D/Model.cpp Normal file
View File

@@ -0,0 +1,399 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - 3D Module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/3D/Model.hpp>
#include <Nazara/3D/Config.hpp>
#include <memory>
#include <Nazara/3D/Debug.hpp>
NzModel::NzModel() :
m_animation(nullptr),
m_mesh(nullptr),
m_currentSequence(nullptr),
m_matCount(0),
m_skinCount(0)
{
}
NzModel::NzModel(const NzModel& model) :
m_materials(model.m_materials),
m_animation(model.m_animation),
m_mesh(model.m_mesh),
m_currentSequence(model.m_currentSequence),
m_matCount(model.m_matCount),
m_skinCount(model.m_skinCount)
{
if (m_mesh)
{
if (m_animation)
m_animation->AddResourceReference();
m_mesh->AddResourceReference();
// Nous n'avons des matériaux que si nous avons un mesh
for (const NzMaterial* material : m_materials)
material->AddResourceReference();
}
}
NzModel::~NzModel()
{
Reset();
}
const NzAnimation* NzModel::GetAnimation() const
{
return m_animation;
}
const NzMaterial* NzModel::GetMaterial(unsigned int matIndex) const
{
#if NAZARA_3D_SAFE
if (matIndex >= m_matCount)
{
NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount));
return nullptr;
}
#endif
return m_materials[matIndex];
}
const NzMaterial* NzModel::GetMaterial(unsigned int skinIndex, unsigned int matIndex) const
{
#if NAZARA_3D_SAFE
if (skinIndex >= m_skinCount)
{
NazaraError("Skin index out of range (" + NzString::Number(skinIndex) + " >= " + NzString::Number(m_skinCount));
return nullptr;
}
if (matIndex >= m_matCount)
{
NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount));
return nullptr;
}
#endif
return m_materials[matIndex];
}
unsigned int NzModel::GetMaterialCount() const
{
return m_matCount;
}
unsigned int NzModel::GetSkinCount() const
{
return m_skinCount;
}
const NzMesh* NzModel::GetMesh() const
{
return m_mesh;
}
nzSceneNodeType NzModel::GetSceneNodeType() const
{
return nzSceneNodeType_Model;
}
const NzSkeleton* NzModel::GetSkeleton() const
{
return &m_skeleton;
}
bool NzModel::HasAnimation() const
{
return m_animation != nullptr;
}
bool NzModel::LoadFromFile(const NzString& meshPath, const NzMeshParams& meshParameters, const NzModelParameters& modelParameters)
{
///TODO: ResourceManager
std::unique_ptr<NzMesh> mesh(new NzMesh);
if (!mesh->LoadFromFile(meshPath, meshParameters))
{
NazaraError("Failed to load mesh");
return false;
}
mesh->SetPersistent(false, false);
SetMesh(mesh.release(), modelParameters);
return true;
}
bool NzModel::LoadFromMemory(const void* data, std::size_t size, const NzMeshParams& meshParameters, const NzModelParameters& modelParameters)
{
std::unique_ptr<NzMesh> mesh(new NzMesh);
if (!mesh->LoadFromMemory(data, size, meshParameters))
{
NazaraError("Failed to load mesh");
return false;
}
mesh->SetPersistent(false, false);
SetMesh(mesh.release(), modelParameters);
return true;
}
bool NzModel::LoadFromStream(NzInputStream& stream, const NzMeshParams& meshParameters, const NzModelParameters& modelParameters)
{
std::unique_ptr<NzMesh> mesh(new NzMesh);
if (!mesh->LoadFromStream(stream, meshParameters))
{
NazaraError("Failed to load mesh");
return false;
}
mesh->SetPersistent(false, false);
SetMesh(mesh.release(), modelParameters);
return true;
}
void NzModel::Reset()
{
m_matCount = 0;
m_skinCount = 0;
if (m_mesh)
{
m_mesh->RemoveResourceReference();
m_mesh = nullptr;
m_skeleton.Destroy();
if (m_animation)
{
m_animation->RemoveResourceReference();
m_animation = nullptr;
}
// Nous n'avons des matériaux que si nous avons un mesh
for (const NzMaterial* material : m_materials)
material->RemoveResourceReference();
m_materials.clear();
}
}
bool NzModel::SetAnimation(const NzAnimation* animation)
{
#if NAZARA_3D_SAFE
if (!m_mesh)
{
NazaraError("Model has no animation");
return false;
}
if (animation)
{
if (!animation->IsValid())
{
NazaraError("Invalid animation");
return false;
}
if (animation->GetType() != m_mesh->GetAnimationType())
{
NazaraError("Animation type must match mesh animation type");
return false;
}
if (animation->GetType() == nzAnimationType_Skeletal && animation->GetJointCount() != m_mesh->GetJointCount())
{
NazaraError("Animation joint count must match mesh joint count");
return false;
}
}
#endif
m_animation = animation;
if (m_animation)
{
m_animation->AddResourceReference();
SetSequence(0);
}
return true;
}
void NzModel::SetMaterial(unsigned int matIndex, const NzMaterial* material)
{
#if NAZARA_3D_SAFE
if (matIndex >= m_matCount)
{
NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount));
return;
}
#endif
m_materials[matIndex]->RemoveResourceReference();
if (material)
m_materials[matIndex] = material;
else
m_materials[matIndex] = NzMaterial::GetDefault();
m_materials[matIndex]->AddResourceReference();
}
void NzModel::SetMaterial(unsigned int skinIndex, unsigned int matIndex, const NzMaterial* material)
{
#if NAZARA_3D_SAFE
if (skinIndex >= m_skinCount)
{
NazaraError("Skin index out of range (" + NzString::Number(skinIndex) + " >= " + NzString::Number(m_skinCount));
return;
}
if (matIndex >= m_matCount)
{
NazaraError("Material index out of range (" + NzString::Number(matIndex) + " >= " + NzString::Number(m_matCount));
return;
}
#endif
unsigned int index = skinIndex*m_matCount + matIndex;
m_materials[index]->RemoveResourceReference();
if (material)
m_materials[index] = material;
else
m_materials[index] = NzMaterial::GetDefault();
m_materials[index]->AddResourceReference();
}
void NzModel::SetMesh(const NzMesh* mesh, const NzModelParameters& modelParameters)
{
Reset();
if (mesh)
{
m_mesh = mesh;
m_mesh->AddResourceReference();
if (m_mesh->GetAnimationType() == nzAnimationType_Skeletal)
m_skeleton = *mesh->GetSkeleton(); // Copie du squelette template
if (modelParameters.loadAnimation)
{
NzString animationPath = m_mesh->GetAnimation();
if (!animationPath.IsEmpty())
{
std::unique_ptr<NzAnimation> animation(new NzAnimation);
if (animation->LoadFromFile(animationPath, modelParameters.animationParams) && SetAnimation(animation.get()))
{
animation->SetPersistent(false);
animation.release();
}
else
NazaraWarning("Failed to load animation");
}
}
m_interpolation = 0.f;
m_matCount = mesh->GetMaterialCount();
m_materials.resize(m_matCount, NzMaterial::GetDefault());
if (modelParameters.loadMaterials)
{
for (unsigned int i = 0; i < m_matCount; ++i)
{
NzString mat = mesh->GetMaterial(i);
if (!mat.IsEmpty())
{
std::unique_ptr<NzMaterial> material(new NzMaterial);
if (material->LoadFromFile(mat, modelParameters.materialParams))
{
material->SetPersistent(false, false); // Pas de vérification des références car nous n'y avons pas encore accroché de référence
m_materials[i] = material.release();
}
else
NazaraWarning("Failed to load material #" + NzString::Number(i));
}
}
}
for (const NzMaterial* material : m_materials)
material->AddResourceReference();
}
}
void NzModel::SetSkinCount(unsigned int skinCount)
{
#if NAZARA_3D_SAFE
if (skinCount == 0)
{
NazaraError("Skin count must be over 0");
return;
}
#endif
m_materials.resize(m_matCount*skinCount, NzMaterial::GetDefault());
m_skinCount = skinCount;
}
bool NzModel::SetSequence(const NzString& sequenceName)
{
#if NAZARA_3D_SAFE
if (!m_animation)
{
NazaraError("Model has no animation");
return false;
}
#endif
m_currentSequence = m_animation->GetSequence(sequenceName);
if (m_currentSequence)
{
m_nextFrame = m_currentSequence->firstFrame;
return true;
}
else
{
NazaraError("Sequence not found");
return false;
}
}
void NzModel::SetSequence(unsigned int sequenceIndex)
{
#if NAZARA_3D_SAFE
if (!m_animation)
{
NazaraError("Model has no animation");
return;
}
#endif
m_currentSequence = m_animation->GetSequence(sequenceIndex);
m_nextFrame = m_currentSequence->firstFrame;
}
void NzModel::Update(float elapsedTime)
{
#if NAZARA_3D_SAFE
if (!m_animation)
{
NazaraError("Model has no animation");
return;
}
#endif
m_interpolation += m_currentSequence->frameRate * elapsedTime;
while (m_interpolation > 1.f)
{
m_interpolation -= 1.f;
m_currentFrame = m_nextFrame;
if (++m_nextFrame >= m_currentSequence->firstFrame+m_currentSequence->frameCount)
m_nextFrame = m_currentSequence->firstFrame;
}
m_mesh->Animate(m_animation, m_currentFrame, m_nextFrame, m_interpolation);
}

View File

@@ -0,0 +1,8 @@
// Copyright (C) 2012 Jérôme Leclercq
// This file is part of the "Nazara Engine - 3D Module"
// For conditions of distribution and use, see copyright notice in Config.hpp
#include <Nazara/3D/SceneNode.hpp>
#include <Nazara/3D/Debug.hpp>
NzSceneNode::~NzSceneNode() = default;

View File

@@ -55,9 +55,9 @@ const NzTexture* NzMaterial::GetDiffuseMap() const
return m_diffuseMap;
}
nzBlendFunc NzMaterial::GetDstAlpha() const
nzBlendFunc NzMaterial::GetDstBlend() const
{
return m_dstAlpha;
return m_dstBlend;
}
nzFaceCulling NzMaterial::GetFaceCulling() const
@@ -85,9 +85,9 @@ const NzTexture* NzMaterial::GetSpecularMap() const
return m_specularMap;
}
nzBlendFunc NzMaterial::GetSrcAlpha() const
nzBlendFunc NzMaterial::GetSrcBlend() const
{
return m_srcAlpha;
return m_srcBlend;
}
nzRendererComparison NzMaterial::GetZTestCompare() const
@@ -142,12 +142,12 @@ void NzMaterial::Reset()
m_alphaBlendingEnabled = false;
m_ambientColor = NzColor::Black;
m_diffuseColor = NzColor::White;
m_dstAlpha = nzBlendFunc_Zero;
m_dstBlend = nzBlendFunc_Zero;
m_faceCulling = nzFaceCulling_Back;
m_faceFilling = nzFaceFilling_Fill;
m_shininess = 0;
m_specularColor = NzColor::White;
m_srcAlpha = nzBlendFunc_One;
m_srcBlend = nzBlendFunc_One;
m_zTestCompareFunc = nzRendererComparison_LessOrEqual;
m_zTestEnabled = true;
m_zWriteEnabled = true;
@@ -173,9 +173,9 @@ void NzMaterial::SetDiffuseMap(const NzTexture* map)
m_diffuseMap->AddResourceReference();
}
void NzMaterial::SetDstAlpha(nzBlendFunc func)
void NzMaterial::SetDstBlend(nzBlendFunc func)
{
m_dstAlpha = func;
m_dstBlend = func;
}
void NzMaterial::SetFaceCulling(nzFaceCulling culling)
@@ -208,9 +208,9 @@ void NzMaterial::SetSpecularMap(const NzTexture* map)
m_specularMap->AddResourceReference();
}
void NzMaterial::SetSrcAlpha(nzBlendFunc func)
void NzMaterial::SetSrcBlend(nzBlendFunc func)
{
m_srcAlpha = func;
m_srcBlend = func;
}
void NzMaterial::SetZTestCompare(nzRendererComparison compareFunc)

View File

@@ -11,6 +11,7 @@
#include <Nazara/Renderer/Context.hpp>
#include <Nazara/Renderer/DebugDrawer.hpp>
#include <Nazara/Renderer/HardwareBuffer.hpp>
#include <Nazara/Renderer/Material.hpp>
#include <Nazara/Renderer/RenderTarget.hpp>
#include <Nazara/Renderer/Shader.hpp>
#include <Nazara/Renderer/ShaderImpl.hpp>
@@ -49,6 +50,11 @@ namespace
NzMatrix4f s_matrix[totalMatrixCount];
int s_matrixLocation[totalMatrixCount];
bool s_matrixUpdated[totalMatrixCount];
nzBlendFunc s_srcBlend;
nzBlendFunc s_dstBlend;
nzFaceCulling s_faceCulling;
nzFaceFilling s_faceFilling;
nzRendererComparison s_depthFunc;
nzRendererComparison s_stencilCompare;
nzStencilOperation s_stencilFail;
nzStencilOperation s_stencilPass;
@@ -69,6 +75,57 @@ namespace
unsigned int s_stencilReference;
}
void NzRenderer::ApplyMaterial(const NzMaterial* material)
{
///FIXME; Bouger vers Material::Apply ?
#if NAZARA_RENDERER_SAFE
if (!material)
{
NazaraError("Invalid material");
return;
}
#endif
NzShader* shader = s_shader;
int ambientColorLocation = shader->GetUniformLocation("ambientColor");
int diffuseColorLocation = shader->GetUniformLocation("diffuseColor");
int diffuseMapLocation = shader->GetUniformLocation("diffuseMap");
int shininessLocation = shader->GetUniformLocation("shininess");
int specularColorLocation = shader->GetUniformLocation("specularColor");
int specularMapLocation = shader->GetUniformLocation("specularMap");
if (ambientColorLocation != -1)
shader->SendColor(ambientColorLocation, material->GetAmbientColor());
if (diffuseColorLocation != -1)
shader->SendColor(diffuseColorLocation, material->GetDiffuseColor());
if (diffuseMapLocation != -1)
shader->SendTexture(diffuseMapLocation, material->GetDiffuseMap());
if (shininessLocation != -1)
shader->SendFloat(shininessLocation, material->GetShininess());
if (specularColorLocation != -1)
shader->SendColor(ambientColorLocation, material->GetSpecularColor());
if (specularMapLocation != -1)
shader->SendTexture(specularMapLocation, material->GetSpecularMap());
if (material->IsAlphaBlendingEnabled())
{
Enable(nzRendererParameter_Blend, true);
SetBlendFunc(material->GetSrcBlend(), material->GetDstBlend());
}
else
Enable(nzRendererParameter_Blend, false);
Enable(nzRendererParameter_DepthTest, material->IsZTestEnabled());
Enable(nzRendererParameter_DepthWrite, material->IsZWriteEnabled());
SetDepthFunc(material->GetZTestCompare());
}
void NzRenderer::Clear(unsigned long flags)
{
#ifdef NAZARA_DEBUG
@@ -377,8 +434,12 @@ bool NzRenderer::Initialize()
s_matrixUpdated[i] = false;
}
s_dstBlend = nzBlendFunc_Zero;
s_faceCulling = nzFaceCulling_Back;
s_faceFilling = nzFaceFilling_Fill;
s_indexBuffer = nullptr;
s_shader = nullptr;
s_srcBlend = nzBlendFunc_One;
s_stencilCompare = nzRendererComparison_Always;
s_stencilFail = nzStencilOperation_Keep;
s_stencilFuncUpdated = true;
@@ -502,7 +563,7 @@ bool NzRenderer::IsInitialized()
return s_moduleReferenceCounter != 0;
}
void NzRenderer::SetBlendFunc(nzBlendFunc src, nzBlendFunc dest)
void NzRenderer::SetBlendFunc(nzBlendFunc srcBlend, nzBlendFunc destBlend)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
@@ -512,7 +573,12 @@ void NzRenderer::SetBlendFunc(nzBlendFunc src, nzBlendFunc dest)
}
#endif
glBlendFunc(NzOpenGL::BlendFunc[src], NzOpenGL::BlendFunc[dest]);
if (s_srcBlend != srcBlend || s_dstBlend != destBlend)
{
glBlendFunc(NzOpenGL::BlendFunc[srcBlend], NzOpenGL::BlendFunc[destBlend]);
s_srcBlend = srcBlend;
s_dstBlend = destBlend;
}
}
void NzRenderer::SetClearColor(const NzColor& color)
@@ -567,6 +633,23 @@ void NzRenderer::SetClearStencil(unsigned int value)
glClearStencil(value);
}
void NzRenderer::SetDepthFunc(nzRendererComparison compareFunc)
{
#ifdef NAZARA_DEBUG
if (NzContext::GetCurrent() == nullptr)
{
NazaraError("No active context");
return;
}
#endif
if (s_depthFunc != compareFunc)
{
glDepthFunc(NzOpenGL::RendererComparison[compareFunc]);
s_depthFunc = compareFunc;
}
}
void NzRenderer::SetFaceCulling(nzFaceCulling cullingMode)
{
#ifdef NAZARA_DEBUG
@@ -577,7 +660,11 @@ void NzRenderer::SetFaceCulling(nzFaceCulling cullingMode)
}
#endif
glCullFace(NzOpenGL::FaceCulling[cullingMode]);
if (s_faceCulling != cullingMode)
{
glCullFace(NzOpenGL::FaceCulling[cullingMode]);
s_faceCulling = cullingMode;
}
}
void NzRenderer::SetFaceFilling(nzFaceFilling fillingMode)
@@ -590,7 +677,11 @@ void NzRenderer::SetFaceFilling(nzFaceFilling fillingMode)
}
#endif
glPolygonMode(GL_FRONT_AND_BACK, NzOpenGL::FaceFilling[fillingMode]);
if (s_faceFilling != fillingMode)
{
glPolygonMode(GL_FRONT_AND_BACK, NzOpenGL::FaceFilling[fillingMode]);
s_faceFilling = fillingMode;
}
}
bool NzRenderer::SetIndexBuffer(const NzIndexBuffer* indexBuffer)

View File

@@ -219,6 +219,25 @@ unsigned int NzAnimation::GetFrameCount() const
return m_impl->frameCount;
}
unsigned int NzAnimation::GetJointCount() const
{
#if NAZARA_UTILITY_SAFE
if (!m_impl)
{
NazaraError("Animation not created");
return 0;
}
if (m_impl->type != nzAnimationType_Skeletal)
{
NazaraError("Animation is not skeletal");
return 0;
}
#endif
return m_impl->jointCount;
}
NzSequence* NzAnimation::GetSequence(const NzString& sequenceName)
{
#if NAZARA_UTILITY_SAFE