j'ai continué trankilou le développement de mon terrain, et je dois dire qu'il commence à être sympa, j'ai viré les points négatifs
il dispose d'un splatting shader et suport des 'unlimited light", le fog est à revoir (le rendu reste très correct sans)
il est toujours basé sur le quadtree mais intègre également un lod "clasique" je cherche actuellement des algorithme pour un lod plus poussé style c-bdam ou rtin (si quelqu'un a un sample)
je bosse en ce moment sur le raccord entre les quads et le mode d'édition
je compte revoir le shader pour qu'il supporte plusieurs textures en une, comme ça il y aura la texture référence, la colormap, la texture "pack" et le bumpmap "pack"
l'app pour générer mes terrains via la libnoise (sur le portable core i3, hd5165) avec compiz

edit: visualisez l'image dans un autre onglet, le forum semble redimentionner l'image, c'est pas terrible
ce n'est pas vraiment sinificatif mais j'ai 540fps pour +1.5M de poly sur le fix (hd5770, phenon II x4 10) avec compiz d'activé ...
les méthodes de calcul sont thread-safe (enfin dans mon engine sa passe nikel, toutes les fonction OnAnimated sont dans un thread séparé)
le rendu est "static" c'est a dire que le changement de position se fait directement au niveaux des vertex pour les quads ce qui a permis de supprimmer les changements de matrices pour chaque quad
c'est aussi valable pour les matériaux, et les rendus de debug
ps: pour information dans mon engine, il n'y aura pas de moteur de terrain, mais un heightfield général optimisé, qui sera utilisé aussi bien pour le terrain que pour l'eau, seul le shader changera
le "layer" du terrain peut être généré par texture ou algorithme ou par la libnoise, peut-être que ce serait bien pour aip ?
ps2: tmyke on voit tous le temps tous les topics comme "non lu" dans cette partie
"methode" de calcule du lod
Code c++ :
void Quad::calculateIndice()
{
const u32 step = 1 << currentLOD;
const u32 step2 = 1 << (currentLOD < 1 ? 1 : currentLOD-1);
if(currentLOD > 1)
{
if(root->getAdjacentQuad(this, HeightField::HEQ_OUEST)->getCalculatedLod() <= calculateLOD)
{
for(u32 y = 0; y < Height-step2-1; y+=step)
{
const u32 n = y*Width;
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step2*Height);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back((y+step2)*Width + step2*Height);
RenderMesh->getIndexBuffer().push_back(n + step2*Height);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back((y+step2)*Width + step2*Height);
RenderMesh->getIndexBuffer().push_back((y+step2)*Width + step2*Height + step);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back((y+step2)*Width + step2*Height + step);
RenderMesh->getIndexBuffer().push_back(n + step);
}
}
else
{
for(u32 y = 0; y < Height-step2-1; y+=step)
{
const u32 n = y*Width;
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
}
}
if(root->getAdjacentQuad(this, HeightField::HEQ_SUD)->getCalculatedLod() <= calculateLOD)
{
for(u32 x = 0; x < Width-step2-1; x+=step)
{
const u32 n = x;
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step2);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step2);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
}
}
else
{
for(u32 x = 0; x < Width-step2-1; x+=step)
{
const u32 n = x;
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
}
}
for(u32 y = step; y < Height-1; y+= step)
{
const u32 w = y*Width;
for(u32 x = step; x < Width-1; x+=step)
{
const u32 n = w+x;
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
}
}
if(root->getAdjacentQuad(this, HeightField::HEQ_EST)->getCalculatedLod() <= calculateLOD)
{
for(u32 y = 0; y < Height-step2-1; y+=step)
{
const u32 n = y*Width+Width-step-1;
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back((y+step2)*Width+Width-step-1 + step2*Height);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back((y+step2)*Width+Width-step-1 + step2*Height);
RenderMesh->getIndexBuffer().push_back((y+step2)*Width+Width-step-1 + step2*Height + step);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step);
}
}
else
{
for(u32 y = 0; y < Height-step2-1; y+=step)
{
const u32 n = y*Width+Width-step-1;
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
}
}
if(root->getAdjacentQuad(this, HeightField::HEQ_NORD)->getCalculatedLod() < calculateLOD)
{
for(u32 x = 0; x < Width-step2-1; x+=step)
{
const u32 n = (Height-step-1)*Width+x;
RenderMesh->getIndexBuffer().push_back(n + step*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step2*Height + step2);
}
}
else
{
for(u32 x = 0; x < Width-step2-1; x+=step)
{
const u32 n = (Height-step-1)*Width+x;
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
}
}
}
else
{
for(u32 y = 0; y < Height-1; y+= step)
{
const u32 w = y*Width;
for(u32 x = 0; x < Width-1; x+=step)
{
const u32 n = w+x;
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step*Height);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
RenderMesh->getIndexBuffer().push_back(n);
RenderMesh->getIndexBuffer().push_back(n + step);
RenderMesh->getIndexBuffer().push_back(n + step*Height + step);
}
}
}
}