Historique des modifications - Message

Message #10999

Sujet: Adapté mon algo à mon code


Type Date Auteur Contenu
Création du message 03-12-2012 10:26:56 johnplayer
J'ai repensé à ta classe bloc. En fait, c'est une mauvaise idée. Dans l'exemple que je t'ai donné, j'ai juste 1 octet par bloc, toi, tu vas avoir une classe par bloc. Je te laisse imaginer le gouffre mémoire que tu vas avoir! Le mieux se serait une classe "MapManager" dérivée de ISceneNode qui contient A x B structures "Zone" qui elle-même contient C x D structures "Chunks". Les classes "Zones" et Chunks" ne contiennent que des données nécessaires (aucune fonctions) à la classe "MapManager". "MapManager" sera chargé de créer, gérer et afficher les buffers contenant les faces à afficher.

Code c++ :


enum MATIERE_BLOC
{
    MB_AIR            = 0,    // si aucune matière
    MB_TRANSPARENCE    = 1,    // si le bloc utilise la transparence (l'eau par exemple)
    MB_MATIERE1        = 2,    // si matière 1
    MB_MATIERE2        = 4,    // si matière 2
};
typedef s32 TypeBloc; // il sera converti en u8 pour limiter la mémoire occupée. Donc le type d'un bloc sera stocké en u8

class MapManager;
struct Zone;
struct Chunk;

class MapManager : public ISceneNode
{
public:
MapManager(...)
: ISceneNode(...)
{
}
virtual ~MapManager()
{
}

// rendu (elle est virtuelle pure dans ISceneNode)
void render()
{
    // culling de zone
    // culling de chunk

    // regroupement intelligent (si plusieurs chunks utilisent les 2 mêmes materials, on fusionne leur buffers pour limiter les draw calls) (à voir pour les perfs)

    // affichage des chunks visibles
}

//! implémentation de OnRegisterSceneNode() car elle est virtuelle pure dans ISceneNode
void OnRegisterSceneNode ()
{
    // on enregistre le node dans les matériaux solides
    SceneManager->registerNodeForRendering(this, scene::ESNRP_SOLID);
    // un scrute tous les materials pour voir s'il contient des matérials transparent (si c'est le cas on l'enregistre dans la liste)
    for(tous les materials)
    {
        if(material utilise la transparence)
        {
            SceneManager->registerNodeForRendering(this, scene::ESNRP_TRANSPARENT);
            // on a pas besoin d'en savoir plus donc on quitte la boucle
            break;
       }
    }
    // on appelle celui de la classe mère (pour les enfants de ce node)
    ISceneNode::OnRegisterSceneNode();
}

//! implémentation de getBoundingBox() car elle est virtuelle pure dans ISceneNode
const aabbox3df & getBoundingBox()
{
}

// update
void updateMap()
{
    // création des 2 buffers pour chaques chunk (2 buffers par chunk car 2 materials differents)
}
void updateZones()
{
}
void updateChunk()
{
}

// Bounding box (pour culling box par exemple)
aabbox3df getBBofZone(const vector2d<u8>& coord_zone=vector2d<u8>(0,0))
{
    // calcul la box en fonction de la position (dans le repére du node MapManager)
    // en fonction de sa place dans le tableau de Zones et du nombre de chunk qu'elle contient.
}
aabbox3df getBBofChunk(const vector2d<u8>& coord_zone=vector2d<u8>(0,0), const vector2d<u8>& coord_chunk=vector2d<u8>(0,0))
{
    // calcul la box en fonction de la position (dans le repére du node MapManager)
    // en fonction de sa place dans le tableau de Zones et  de sa place dans le tableau de Chunks
}

// récupère le bloc adjacent au bloc donné (pour le marching cube)
const u8 getTypeOfRightBloc(const vector2d<u8>& coord_zone=vector2d<u8>(0,0), const vector2d<u8>& coord_chunk=vector2d<u8>(0,0), const vector3d<u8>& coord_bloc=vector3d<u8>(0,0,0)) const
{
    // si le bloc n'existe pas (hors map)
    return MB_AIR;
}
const u8 getTypeOfLeftBloc(const vector2d<u8>& coord_zone=vector2d<u8>(0,0), const vector2d<u8>& coord_chunk=vector2d<u8>(0,0), const vector3d<u8>& coord_bloc=vector3d<u8>(0,0,0)) const
{
    // si le bloc n'existe pas (hors map)
    return MB_AIR;
}
const u8 getTypeOfUpBloc(const vector2d<u8>& coord_zone=vector2d<u8>(0,0), const vector2d<u8>& coord_chunk=vector2d<u8>(0,0), const vector3d<u8>& coord_bloc=vector3d<u8>(0,0,0)) const
{
    // si le bloc n'existe pas (hors map)
    return MB_AIR;
}
const u8 getTypeOfDownBloc(const vector2d<u8>& coord_zone=vector2d<u8>(0,0), const vector2d<u8>& coord_chunk=vector2d<u8>(0,0), const vector3d<u8>& coord_bloc=vector3d<u8>(0,0,0)) const
{
    // si le bloc n'existe pas (hors map)
    return MB_AIR;
}
const u8 getTypeOfForwardBloc(const vector2d<u8>& coord_zone=vector2d<u8>(0,0), const vector2d<u8>& coord_chunk=vector2d<u8>(0,0), const vector3d<u8>& coord_bloc=vector3d<u8>(0,0,0)) const
{
    // si le bloc n'existe pas (hors map)
    return MB_AIR;
}
const u8 getTypeOfBackwardBloc(const vector2d<u8>& coord_zone=vector2d<u8>(0,0), const vector2d<u8>& coord_chunk=vector2d<u8>(0,0), const vector3d<u8>& coord_bloc=vector3d<u8>(0,0,0)) const
{
    // si le bloc n'existe pas (hors map)
    return MB_AIR;
}

// et ainsi de suite, suivant les besoins

protected:
Zone* ListeZones[10][10]; // une map = 10x10 zones par exemple

};

struct Zone
{
Chunk* ListeChunks[10][10];
};
struct Chunk
{
u8* ListeBloc[16][16][25]; // exemple un bloc de matière 1 et utilisant la transparence : ListeBloc[x][y][z] = u8( MB_MATIERE1 | MB_TRANSPARENT );
SMaterial material1, material2;
};



Avec cette méthode, la gestion sera plus facile et moins coûteuse en mémoire. Le SDZ a un tuto sur la dérivation d'un ISceneNode (que tu as déjà vu je pense).

Le mieux serait que tu créés un projet de base, tu créés un CubeNode (dérivé de ISceneNode) qui dessine un JUSTE UN TRIANGLE à l'écran, puis un cube pour te faire la main sur le fonctionnement. Une fois que tu auras réussi cet exercice de base tu pourras faire quelque chose avec le code de ce que je t'ai donné au-dessus.

Retour

Options Liens officiels Caractéristiques Statistiques Communauté
Préférences cookies
Corrections
irrlicht
irrklang
irredit
irrxml
Propulsé par Django
xhtml 1.0
css 2.1
884 membres
1440 sujets
11337 messages
Dernier membre inscrit: Saidov17
155 invités en ligne
membre en ligne: -
RSS Feed