2010-06-21 6 views
4

Je suis en train de trouver mes voies dans le C de la terre et je suis de plus en plus confus maintenant. L'application jouet est un moteur OpenGL très basique. Alors, voici le (je suppose simplement) problème: Je voudrais gérer des mailles de différentes données de sommet, donc je l'aurais par exemple Maintenant, j'ai besoin d'une classe Mesh qui contient les données et les dessine. J'ai essayé quelque chose comme ceci:modèles vs commutateur

template<class T> 
class Mesh 
{ 
    public: 
     Mesh(); 
     ~Mesh(); 

     void load(const T * vertices, int num); 
     void draw(); 

    protected: 
     T * vertices_; 

};

Les différents sommets doivent être chargés et dessinés différemment, ce qui peut être fait avec une spécialisation de gabarit. Mon problème est que j'aime avoir une autre classe qui contient des instances d'objets Mesh, mais les membres de classe modélisés ne sont évidemment pas autorisés. L'autre solution que je peux penser est de maintenir des pointeurs sur la structure de base Vertex dans Mesh, passer un identifiant pour le type Vertex utilisé et ensuite utiliser les instructions switch dans load() et draw() pour autoriser les différentes implémentations .

Quelle est la meilleure façon d'y parvenir?

Toute aide est grandement appréciée.

Répondre

7

Vous pouvez utiliser l'héritage et des fonctions virtuelles. Par exemple:

class MeshBase 
{ 
public: 
    virtual ~MeshBase() { } 
    virtual void draw() = 0; 
}; 

template <typename T> 
class Mesh : public MeshBase 
{ 
public: 
    virtual void draw() { } 
    // ... 
}; 

Avec cette approche, vous pouvez stocker des pointeurs vers la classe de base MeshBase dans un récipient.

Idéalement, vous pouvez utiliser un conteneur de pointeur, qui va gérer les pointeurs pour vous, ou vous pouvez utiliser un conteneur de pointeurs intelligents (par exemple, un std::vector<std::shared_ptr<MeshBase> >, si votre mise en œuvre comprend shared_ptr, sinon, it can be found in a number of places).

Je vous recommande également de stocker les vertices dans un conteneur de la classe Mesh, plutôt que d'utiliser l'allocation dynamique manuelle et la gestion de la mémoire.

+0

Le modèle sur Mesh peut-il également être supprimé étant donné l'héritage des classes Vertex? – drfrogsplat

+0

@drfrogsplat: Uniquement si vous voulez stocker des pointeurs sur des sommets individuels, ce qui n'est probablement pas souhaitable pour des raisons de performances. Je n'utiliserais pas l'héritage du tout pour une classe de vertex: implémentez simplement chaque type de vertex en tant que classe indépendante ou en utilisant un template (c'est par exemple ce que fait OpenSceneGraph). –

+2

Essayez de préférer 'boost :: ptr_vector' à' std :: vector 'si vous avez accès à boost (cela fait partie de Boost.PointerContainer). En C++ 0x, vous pouvez utiliser 'std :: vector ' pour éviter la dépendance au boost. –

0

Je vous recommande de ne pas modéliser votre classe de maillage mais de la rendre capable de gérer différents types de données de sommet. Ceci est un problème graphique commun et est abordé dans DirectX avec la notion de lier ensemble différents "flux" de données pour dessiner la géométrie. En d'autres termes, vos normales seraient un flux de données différent de vos données de position. Ensuite, votre objet maillage devient un conteneur de plusieurs flux de données et ne serait pas lié à un format de sommet particulier au moment de la compilation. Je ne connais pas OpenGL aussi, mais j'imagine qu'il existe un concept similaire.

Voir: http://msdn.microsoft.com/en-us/library/bb147299(VS.85).aspx

0

@bshields a un point, vous devez représenter les données sommet de la manière la plus efficace, ce qui dans le cas d'OpenGL sont Vertex Buffer Objects (VBOs): http://www.opengl.org/wiki/Vertex_Buffer_Object

Compte tenu de la lignes directrices exposées dans le lien ci-dessus - qui vont dans le sens de ce que dit @James McNellis de ne pas utiliser l'héritage pour vos types Vertex - et le fait que le chargement et le dessin dépendent probablement du type de vertex et du type d'entrée) Je vous suggère d'appliquer le modèle de stratégie en utilisant le polymorphisme statique, comme indiqué dans la réponse à cette autre question: template strategy pattern

+0

Merci. draw() utilise déjà un wrapper pour les VBO. Je devrais également aligner les données correctement ... Le poste que vous avez lié est intéressant, mais il semble que c'est trop pour moi en ce moment. Bookmarked quand même. – bbtrb