Graphics: Remake DepthRender[Queue|Technique]
Former-commit-id: c4d8d4d28d02822273ebe7dca3e468ea156af674
This commit is contained in:
@@ -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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user