Graphics: Remake DepthRender[Queue|Technique]

Former-commit-id: c4d8d4d28d02822273ebe7dca3e468ea156af674
This commit is contained in:
Lynix
2015-07-05 23:43:35 +02:00
parent 6870148314
commit 1f2e810927
4 changed files with 387 additions and 428 deletions

View File

@@ -7,76 +7,58 @@
#include <Nazara/Graphics/Material.hpp>
#include <Nazara/Graphics/Debug.hpp>
///TODO: Remplacer les sinus/cosinus par une lookup table (va booster les perfs d'un bon x10)
NzDepthRenderQueue::NzDepthRenderQueue()
{
// Material
m_baseMaterial = NzMaterial::New();
m_baseMaterial->Enable(nzRendererParameter_ColorWrite, false);
m_baseMaterial->Enable(nzRendererParameter_FaceCulling, false);
//m_baseMaterial->SetFaceCulling(nzFaceSide_Front);
}
void NzDepthRenderQueue::AddBillboard(const NzMaterial* material, const NzVector3f& position, const NzVector2f& size, const NzVector2f& sinCos, const NzColor& color)
{
NazaraAssert(material, "Invalid material");
if (IsMaterialSuitable(material))
billboards.push_back(BillboardData{color, position, size, sinCos});
if (!IsMaterialSuitable(material))
return;
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
NzForwardRenderQueue::AddBillboard(material, position, size, sinCos, color);
}
void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const NzVector2f> sizePtr, NzSparsePtr<const NzVector2f> sinCosPtr, NzSparsePtr<const NzColor> colorPtr)
{
///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
NazaraAssert(material, "Invalid material");
if (!IsMaterialSuitable(material))
return;
NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
if (!sinCosPtr)
sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
if (!colorPtr)
colorPtr.Reset(&NzColor::White, 0); // Pareil
unsigned int prevSize = billboards.size();
billboards.resize(prevSize + count);
BillboardData* billboardData = &billboards[prevSize];
for (unsigned int i = 0; i < count; ++i)
{
billboardData->center = *positionPtr++;
billboardData->color = *colorPtr++;
billboardData->sinCos = *sinCosPtr++;
billboardData->size = *sizePtr++;
billboardData++;
}
NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
}
void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const NzVector2f> sizePtr, NzSparsePtr<const NzVector2f> sinCosPtr, NzSparsePtr<const float> alphaPtr)
{
///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
NazaraAssert(material, "Invalid material");
if (!IsMaterialSuitable(material))
return;
NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
if (!sinCosPtr)
sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
float defaultAlpha = 1.f;
if (!alphaPtr)
alphaPtr.Reset(&defaultAlpha, 0); // Pareil
unsigned int prevSize = billboards.size();
billboards.resize(prevSize + count);
BillboardData* billboardData = &billboards[prevSize];
for (unsigned int i = 0; i < count; ++i)
{
billboardData->center = *positionPtr++;
billboardData->color = NzColor(255, 255, 255, static_cast<nzUInt8>(255.f * (*alphaPtr++)));
billboardData->sinCos = *sinCosPtr++;
billboardData->size = *sizePtr++;
billboardData++;
}
NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
}
void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const NzVector2f> sizePtr, NzSparsePtr<const float> anglePtr, NzSparsePtr<const NzColor> colorPtr)
@@ -86,129 +68,57 @@ void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int
if (!IsMaterialSuitable(material))
return;
///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
float defaultRotation = 0.f;
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
if (!anglePtr)
anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
if (!colorPtr)
colorPtr.Reset(&NzColor::White, 0); // Pareil
unsigned int prevSize = billboards.size();
billboards.resize(prevSize + count);
BillboardData* billboardData = &billboards[prevSize];
for (unsigned int i = 0; i < count; ++i)
{
float sin = std::sin(NzToRadians(*anglePtr));
float cos = std::cos(NzToRadians(*anglePtr));
anglePtr++;
billboardData->center = *positionPtr++;
billboardData->color = *colorPtr++;
billboardData->sinCos.Set(sin, cos);
billboardData->size = *sizePtr++;
billboardData++;
}
NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr);
}
void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const NzVector2f> sizePtr, NzSparsePtr<const float> anglePtr, NzSparsePtr<const float> alphaPtr)
{
///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
NazaraAssert(material, "Invalid material");
if (!IsMaterialSuitable(material))
return;
float defaultRotation = 0.f;
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
if (!anglePtr)
anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
float defaultAlpha = 1.f;
if (!alphaPtr)
alphaPtr.Reset(&defaultAlpha, 0); // Pareil
unsigned int prevSize = billboards.size();
billboards.resize(prevSize + count);
BillboardData* billboardData = &billboards[prevSize];
for (unsigned int i = 0; i < count; ++i)
{
float sin = std::sin(NzToRadians(*anglePtr));
float cos = std::cos(NzToRadians(*anglePtr));
anglePtr++;
billboardData->center = *positionPtr++;
billboardData->color = NzColor(255, 255, 255, static_cast<nzUInt8>(255.f * (*alphaPtr++)));
billboardData->sinCos.Set(sin, cos);
billboardData->size = *sizePtr++;
billboardData++;
}
NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
}
void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const float> sizePtr, NzSparsePtr<const NzVector2f> sinCosPtr, NzSparsePtr<const NzColor> colorPtr)
{
///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
NazaraAssert(material, "Invalid material");
if (!IsMaterialSuitable(material))
return;
NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
if (!sinCosPtr)
sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
if (!colorPtr)
colorPtr.Reset(&NzColor::White, 0); // Pareil
unsigned int prevSize = billboards.size();
billboards.resize(prevSize + count);
BillboardData* billboardData = &billboards[prevSize];
for (unsigned int i = 0; i < count; ++i)
{
billboardData->center = *positionPtr++;
billboardData->color = *colorPtr++;
billboardData->sinCos = *sinCosPtr++;
billboardData->size.Set(*sizePtr++);
billboardData++;
}
NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, colorPtr);
}
void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const float> sizePtr, NzSparsePtr<const NzVector2f> sinCosPtr, NzSparsePtr<const float> alphaPtr)
{
///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
NazaraAssert(material, "Invalid material");
if (!IsMaterialSuitable(material))
return;
NzVector2f defaultSinCos(0.f, 1.f); // sin(0) = 0, cos(0) = 1
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
if (!sinCosPtr)
sinCosPtr.Reset(&defaultSinCos, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
float defaultAlpha = 1.f;
if (!alphaPtr)
alphaPtr.Reset(&defaultAlpha, 0); // Pareil
unsigned int prevSize = billboards.size();
billboards.resize(prevSize + count);
BillboardData* billboardData = &billboards[prevSize];
for (unsigned int i = 0; i < count; ++i)
{
billboardData->center = *positionPtr++;
billboardData->color = NzColor(255, 255, 255, static_cast<nzUInt8>(255.f * (*alphaPtr++)));
billboardData->sinCos = *sinCosPtr++;
billboardData->size.Set(*sizePtr++);
billboardData++;
}
NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, sinCosPtr, alphaPtr);
}
void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const float> sizePtr, NzSparsePtr<const float> anglePtr, NzSparsePtr<const NzColor> colorPtr)
@@ -218,80 +128,33 @@ void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int
if (!IsMaterialSuitable(material))
return;
///DOC: sinCosPtr et colorPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
float defaultRotation = 0.f;
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
if (!anglePtr)
anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
if (!colorPtr)
colorPtr.Reset(&NzColor::White, 0); // Pareil
unsigned int prevSize = billboards.size();
billboards.resize(prevSize + count);
BillboardData* billboardData = &billboards[prevSize];
for (unsigned int i = 0; i < count; ++i)
{
float sin = std::sin(NzToRadians(*anglePtr));
float cos = std::cos(NzToRadians(*anglePtr));
anglePtr++;
billboardData->center = *positionPtr++;
billboardData->color = *colorPtr++;
billboardData->sinCos.Set(sin, cos);
billboardData->size.Set(*sizePtr++);
billboardData++;
}
NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, colorPtr);
}
void NzDepthRenderQueue::AddBillboards(const NzMaterial* material, unsigned int count, NzSparsePtr<const NzVector3f> positionPtr, NzSparsePtr<const float> sizePtr, NzSparsePtr<const float> anglePtr, NzSparsePtr<const float> alphaPtr)
{
///DOC: sinCosPtr et alphaPtr peuvent être nuls, ils seront remplacés respectivement par Vector2f(0.f, 1.f) et Color::White
NazaraAssert(material, "Invalid material");
if (!IsMaterialSuitable(material))
return;
float defaultRotation = 0.f;
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
if (!anglePtr)
anglePtr.Reset(&defaultRotation, 0); // L'astuce ici est de mettre le stride sur zéro, rendant le pointeur immobile
float defaultAlpha = 1.f;
if (!alphaPtr)
alphaPtr.Reset(&defaultAlpha, 0); // Pareil
unsigned int prevSize = billboards.size();
billboards.resize(prevSize + count);
BillboardData* billboardData = &billboards[prevSize];
for (unsigned int i = 0; i < count; ++i)
{
float sin = std::sin(NzToRadians(*anglePtr));
float cos = std::cos(NzToRadians(*anglePtr));
anglePtr++;
billboardData->center = *positionPtr++;
billboardData->color = NzColor(255, 255, 255, static_cast<nzUInt8>(255.f * (*alphaPtr++)));
billboardData->sinCos.Set(sin, cos);
billboardData->size.Set(*sizePtr++);
billboardData++;
}
NzForwardRenderQueue::AddBillboards(material, count, positionPtr, sizePtr, anglePtr, alphaPtr);
}
void NzDepthRenderQueue::AddDrawable(const NzDrawable* drawable)
void NzDepthRenderQueue::AddDirectionalLight(const DirectionalLight& light)
{
#if NAZARA_GRAPHICS_SAFE
if (!drawable)
{
NazaraError("Invalid drawable");
return;
}
#endif
otherDrawables.push_back(drawable);
NazaraAssert(false, "Depth render queue doesn't handle lights");
NazaraUnused(light);
}
void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& meshData, const NzBoxf& meshAABB, const NzMatrix4f& transformMatrix)
@@ -302,25 +165,24 @@ void NzDepthRenderQueue::AddMesh(const NzMaterial* material, const NzMeshData& m
if (!IsMaterialSuitable(material))
return;
auto it = meshes.find(meshData);
if (it == meshes.end())
{
MeshInstanceEntry instanceEntry;
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
if (meshData.indexBuffer)
instanceEntry.indexBufferReleaseSlot.Connect(meshData.indexBuffer->OnIndexBufferRelease, this, &NzDepthRenderQueue::OnIndexBufferInvalidation);
NzForwardRenderQueue::AddMesh(material, meshData, meshAABB, transformMatrix);
}
instanceEntry.vertexBufferReleaseSlot.Connect(meshData.vertexBuffer->OnVertexBufferRelease, this, &NzDepthRenderQueue::OnVertexBufferInvalidation);
void NzDepthRenderQueue::AddPointLight(const PointLight& light)
{
NazaraAssert(false, "Depth render queue doesn't handle lights");
NazaraUnused(light);
}
it = meshes.insert(std::make_pair(meshData, std::move(instanceEntry))).first;
}
std::vector<NzMatrix4f>& instances = it->second.instances;
instances.push_back(transformMatrix);
// Avons-nous suffisamment d'instances pour que le coût d'utilisation de l'instancing soit payé ?
//if (instances.size() >= NAZARA_GRAPHICS_INSTANCING_MIN_INSTANCES_COUNT)
// entry.instancingEnabled = true; // Apparemment oui, activons l'instancing avec ce matériau
void NzDepthRenderQueue::AddSpotLight(const SpotLight& light)
{
NazaraAssert(false, "Depth render queue doesn't handle lights");
NazaraUnused(light);
}
void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexStruct_XYZ_Color_UV* vertices, unsigned int spriteCount, const NzTexture* overlay)
@@ -331,49 +193,17 @@ void NzDepthRenderQueue::AddSprites(const NzMaterial* material, const NzVertexSt
if (!IsMaterialSuitable(material))
return;
basicSprites.push_back(SpriteChain_XYZ_Color_UV({vertices, spriteCount}));
}
if (material->HasDepthMaterial())
material = material->GetDepthMaterial();
else
material = m_baseMaterial;
void NzDepthRenderQueue::Clear(bool fully)
{
NzAbstractRenderQueue::Clear(fully);
basicSprites.clear();
billboards.clear();
otherDrawables.clear();
if (fully)
meshes.clear();
NzForwardRenderQueue::AddSprites(material, vertices, spriteCount, overlay);
}
bool NzDepthRenderQueue::IsMaterialSuitable(const NzMaterial* material) const
{
NazaraAssert(material, "Invalid material");
return material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled();
return material->HasDepthMaterial() || (material->IsEnabled(nzRendererParameter_DepthBuffer) && material->IsEnabled(nzRendererParameter_DepthWrite) && material->IsShadowCastingEnabled());
}
void NzDepthRenderQueue::OnIndexBufferInvalidation(const NzIndexBuffer* indexBuffer)
{
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.indexBuffer == indexBuffer)
it = meshes.erase(it);
else
++it;
}
}
void NzDepthRenderQueue::OnVertexBufferInvalidation(const NzVertexBuffer* vertexBuffer)
{
for (auto it = meshes.begin(); it != meshes.end();)
{
const NzMeshData& renderData = it->first;
if (renderData.vertexBuffer == vertexBuffer)
it = meshes.erase(it);
else
++it;
}
}