Optimized ForwardRenderTechnique
Former-commit-id: a4e035c860ed2fcaeedadd5a41fb9f6251649000
This commit is contained in:
parent
970cf1afc8
commit
241e8fe9d9
|
|
@ -58,7 +58,6 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource
|
|||
|
||||
struct StaticData
|
||||
{
|
||||
NzBoxf aabb;
|
||||
NzMatrix4f transformMatrix;
|
||||
};
|
||||
|
||||
|
|
@ -69,8 +68,8 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource
|
|||
|
||||
struct TransparentModel
|
||||
{
|
||||
NzBoxf aabb;
|
||||
NzMatrix4f transformMatrix;
|
||||
NzSpheref boundingSphere;
|
||||
NzMaterial* material;
|
||||
};
|
||||
|
||||
|
|
@ -85,7 +84,7 @@ class NAZARA_API NzForwardRenderQueue : public NzAbstractRenderQueue, NzResource
|
|||
};
|
||||
|
||||
typedef std::map<const NzSkeletalMesh*, std::vector<SkeletalData>, SkeletalMeshComparator> SkeletalMeshContainer;
|
||||
typedef std::map<const NzStaticMesh*, std::vector<StaticData>, StaticMeshComparator> StaticMeshContainer;
|
||||
typedef std::map<const NzStaticMesh*, std::pair<NzSpheref, std::vector<StaticData>>, StaticMeshComparator> StaticMeshContainer;
|
||||
typedef std::map<const NzMaterial*, std::tuple<bool, SkeletalMeshContainer, StaticMeshContainer>, ModelMaterialComparator> MeshContainer;
|
||||
|
||||
MeshContainer opaqueModels;
|
||||
|
|
|
|||
|
|
@ -122,8 +122,7 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
|
|||
transparentStaticModels.resize(index+1);
|
||||
|
||||
TransparentStaticModel& data = transparentStaticModels.back();
|
||||
data.aabb = staticMesh->GetAABB();
|
||||
data.aabb.Transform(transformMatrix);
|
||||
data.boundingSphere = staticMesh->GetAABB().GetSquaredBoundingSphere();
|
||||
data.material = material;
|
||||
data.mesh = staticMesh;
|
||||
data.transformMatrix = transformMatrix;
|
||||
|
|
@ -140,9 +139,15 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
|
|||
|
||||
auto pair2 = meshMap.insert(std::make_pair(staticMesh, StaticMeshContainer::mapped_type()));
|
||||
if (pair2.second)
|
||||
{
|
||||
staticMesh->AddResourceListener(this, ResourceType_StaticMesh);
|
||||
|
||||
std::vector<StaticData>& staticDataContainer = pair2.first->second;
|
||||
NzSpheref& squaredBoundingSphere = pair2.first->second.first;
|
||||
squaredBoundingSphere.Set(staticMesh->GetAABB().GetSquaredBoundingSphere());
|
||||
///TODO: Écouter le StaticMesh pour repérer tout changement de géométrie
|
||||
}
|
||||
|
||||
std::vector<StaticData>& staticDataContainer = pair2.first->second.second;
|
||||
|
||||
unsigned int instanceCount = staticDataContainer.size() + 1;
|
||||
|
||||
|
|
@ -152,9 +157,6 @@ void NzForwardRenderQueue::AddModel(const NzModel* model)
|
|||
|
||||
staticDataContainer.resize(instanceCount);
|
||||
StaticData& data = staticDataContainer.back();
|
||||
|
||||
data.aabb = staticMesh->GetAABB();
|
||||
data.aabb.Transform(transformMatrix);
|
||||
data.transformMatrix = transformMatrix;
|
||||
}
|
||||
|
||||
|
|
@ -183,16 +185,16 @@ void NzForwardRenderQueue::Sort(const NzCamera& camera)
|
|||
{
|
||||
bool operator()(const std::pair<unsigned int, bool>& index1, const std::pair<unsigned int, bool>& index2)
|
||||
{
|
||||
const NzBoxf& aabb1 = (index1.second) ?
|
||||
queue->transparentStaticModels[index1.first].aabb :
|
||||
queue->transparentSkeletalModels[index1.first].aabb;
|
||||
const NzSpheref& sphere1 = (index1.second) ?
|
||||
queue->transparentStaticModels[index1.first].boundingSphere :
|
||||
queue->transparentSkeletalModels[index1.first].boundingSphere;
|
||||
|
||||
const NzBoxf& aabb2 = (index1.second) ?
|
||||
queue->transparentStaticModels[index2.first].aabb :
|
||||
queue->transparentSkeletalModels[index2.first].aabb;
|
||||
const NzSpheref& sphere2 = (index1.second) ?
|
||||
queue->transparentStaticModels[index2.first].boundingSphere :
|
||||
queue->transparentSkeletalModels[index2.first].boundingSphere;
|
||||
|
||||
NzVector3f position1 = aabb1.GetNegativeVertex(cameraNormal);
|
||||
NzVector3f position2 = aabb2.GetNegativeVertex(cameraNormal);
|
||||
NzVector3f position1 = sphere1.GetNegativeVertex(cameraNormal);
|
||||
NzVector3f position2 = sphere2.GetNegativeVertex(cameraNormal);
|
||||
|
||||
return nearPlane.Distance(position1) < nearPlane.Distance(position2);
|
||||
}
|
||||
|
|
@ -234,6 +236,25 @@ bool NzForwardRenderQueue::OnResourceDestroy(const NzResource* resource, int ind
|
|||
return false; // Nous ne voulons plus recevoir d'évènement de cette ressource
|
||||
}
|
||||
|
||||
bool NzForwardRenderQueue::ModelMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2)
|
||||
{
|
||||
for (unsigned int i = 0; i <= nzShaderFlags_Max; ++i)
|
||||
{
|
||||
const NzShaderProgram* program1 = mat1->GetShaderProgram(nzShaderTarget_Model, i);
|
||||
const NzShaderProgram* program2 = mat2->GetShaderProgram(nzShaderTarget_Model, i);
|
||||
|
||||
if (program1 != program2)
|
||||
return program1 < program2;
|
||||
}
|
||||
|
||||
const NzTexture* diffuseMap1 = mat1->GetDiffuseMap();
|
||||
const NzTexture* diffuseMap2 = mat2->GetDiffuseMap();
|
||||
if (diffuseMap1 != diffuseMap2)
|
||||
return diffuseMap1 < diffuseMap2;
|
||||
|
||||
return mat1 < mat2;
|
||||
}
|
||||
|
||||
bool NzForwardRenderQueue::SkeletalMeshComparator::operator()(const NzSkeletalMesh* subMesh1, const NzSkeletalMesh* subMesh2)
|
||||
{
|
||||
const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer();
|
||||
|
|
@ -253,7 +274,7 @@ bool NzForwardRenderQueue::StaticMeshComparator::operator()(const NzStaticMesh*
|
|||
const NzIndexBuffer* iBuffer1 = subMesh1->GetIndexBuffer();
|
||||
const NzBuffer* buffer1 = (iBuffer1) ? iBuffer1->GetBuffer() : nullptr;
|
||||
|
||||
const NzIndexBuffer* iBuffer2 = subMesh1->GetIndexBuffer();
|
||||
const NzIndexBuffer* iBuffer2 = subMesh2->GetIndexBuffer();
|
||||
const NzBuffer* buffer2 = (iBuffer2) ? iBuffer2->GetBuffer() : nullptr;
|
||||
|
||||
if (buffer1 == buffer2)
|
||||
|
|
@ -269,23 +290,3 @@ bool NzForwardRenderQueue::StaticMeshComparator::operator()(const NzStaticMesh*
|
|||
else
|
||||
return buffer1 < buffer2;
|
||||
}
|
||||
|
||||
bool NzForwardRenderQueue::ModelMaterialComparator::operator()(const NzMaterial* mat1, const NzMaterial* mat2)
|
||||
{
|
||||
///TODO: Comparaison des shaders
|
||||
for (unsigned int i = 0; i <= nzShaderFlags_Max; ++i)
|
||||
{
|
||||
const NzShaderProgram* program1 = mat1->GetShaderProgram(nzShaderTarget_Model, i);
|
||||
const NzShaderProgram* program2 = mat2->GetShaderProgram(nzShaderTarget_Model, i);
|
||||
|
||||
if (program1 != program2)
|
||||
return program1 < program2;
|
||||
}
|
||||
|
||||
const NzTexture* diffuseMap1 = mat1->GetDiffuseMap();
|
||||
const NzTexture* diffuseMap2 = mat2->GetDiffuseMap();
|
||||
if (diffuseMap1 != diffuseMap2)
|
||||
return diffuseMap1 < diffuseMap2;
|
||||
|
||||
return mat1 < mat2;
|
||||
}
|
||||
|
|
|
|||
|
|
@ -199,8 +199,9 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
|||
// Meshs statiques
|
||||
for (auto& subMeshIt : staticContainer)
|
||||
{
|
||||
const NzSpheref& boundingSphere = subMeshIt.second.first;
|
||||
const NzStaticMesh* mesh = subMeshIt.first;
|
||||
std::vector<NzForwardRenderQueue::StaticData>& staticData = subMeshIt.second;
|
||||
std::vector<NzForwardRenderQueue::StaticData>& staticData = subMeshIt.second.second;
|
||||
|
||||
if (!staticData.empty())
|
||||
{
|
||||
|
|
@ -269,7 +270,7 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
|||
// Calcul des lumières les plus proches
|
||||
if (lightCount < m_maxLightsPerObject && !m_renderQueue.lights.empty())
|
||||
{
|
||||
unsigned int count = lightManager.FindClosestLights(&m_renderQueue.lights[0], m_renderQueue.lights.size(), data.aabb.GetCenter(), data.aabb.GetSquaredRadius());
|
||||
unsigned int count = lightManager.FindClosestLights(&m_renderQueue.lights[0], m_renderQueue.lights.size(), data.transformMatrix.GetTranslation() + boundingSphere.GetPosition(), boundingSphere.radius);
|
||||
count -= lightCount;
|
||||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
|
|
@ -356,7 +357,7 @@ void NzForwardRenderTechnique::Draw(const NzScene* scene)
|
|||
// Calcul des lumières les plus proches
|
||||
if (lightCount < m_maxLightsPerObject && !m_renderQueue.lights.empty())
|
||||
{
|
||||
unsigned int count = lightManager.FindClosestLights(&m_renderQueue.lights[0], m_renderQueue.lights.size(), staticModel.aabb.GetCenter(), staticModel.aabb.GetSquaredRadius());
|
||||
unsigned int count = lightManager.FindClosestLights(&m_renderQueue.lights[0], m_renderQueue.lights.size(), matrix.GetTranslation() + staticModel.boundingSphere.GetPosition(), staticModel.boundingSphere.radius);
|
||||
count -= lightCount;
|
||||
|
||||
for (unsigned int i = 0; i < count; ++i)
|
||||
|
|
|
|||
Loading…
Reference in New Issue