IdentifiantMot de passe
Loading...
Mot de passe oublié ?Je m'inscris ! (gratuit)
Navigation

Inscrivez-vous gratuitement
pour pouvoir participer, suivre les réponses en temps réel, voter pour les messages, poser vos propres questions et recevoir la newsletter

Moteurs 3D Discussion :

[Yes::Engine] Vertex format


Sujet :

Moteurs 3D

  1. #1
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 15
    Points : 6
    Points
    6
    Par défaut [Yes::Engine] Vertex format
    Bonjour à tous,


    tout d'abord un grand merci à Laurent Gomila pour son moteur. Je pouvais pas espérer mieux pour apprendre la conception d'un moteur.

    Alors voilà j'ai une question concernant le buffer de vertex. celui là précisément :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    CBuffer<TVertex> m_VertexBuffer;
    La structure TVertex est donnée juste au dessus par

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    struct TVertex
            {
                TVector3F     Position;  ///< Position
                TVector3F     Normal;    ///< Vecteur normal
                unsigned long Color;     ///< Normale
                TVector2F     TexCoords; ///< Coordonnées de texture
            };
    Je voudrais faire en sorte d'y mettre plusieurs formats de vertex ...

    En fait, j'ai essayé d'afficher quelques mesh avec le moteur et me suis retrouvé dans une situation telle que j'avais certains mesh qui possédaient des données du type position, normal, coleurr ou position, coleur enfin plusieurs format de vertex.

    Je me suis donc demandé comment faire pour proposer à l'application un choix du format des vertex. Alors me suis lancé dans plusieurs possibilités mais vu que je suis encore débutant, je n'ai pas vraiment trouvé une solution concrète.

    J'ai essayé dans un premier temps de faire plusieurs structures qui hérite d'un TVertexBase et faire une fonction template de Model pour lui spécifier quel format je choisi. Seulement j'ai un problème que je n'arrive pas à résoudre dans IRenderer. sizeof(TVertexBase) rend 1 ce qui est à priori logique. Je ne sais pas trop comment récupérer la bonne taille d'une structure qui hérite d'une autre. Ceci dit même si je lui donne la bonne taille, les données semblent tronquées lors de l'envoi du buffer.

    Mon autre solution, est que je me dis qu'il y a un coup à jouer avec les typelist mais avant de me lancer dans cette épreuve qui demande beaucoup de recul (ce que je ne pense pas avoir), je voulais donc savoir si quelqu'un avait une idée.

    Voilà,
    merci d'avance

    Tib0000

  2. #2
    Nouveau Candidat au Club
    Profil pro
    Inscrit en
    Septembre 2007
    Messages
    1
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Septembre 2007
    Messages : 1
    Points : 1
    Points
    1
    Par défaut Solution dans WI3D
    Bonjour tib0000,

    J'ai aussi développé un petit moteur 3D qui ressemble pas mal à Yes::Engine.
    J'en profite pour dire aussi un grand bravo à Laurent Gomila pour son travail remarquable ^^.

    Pour la gestion des buffers avec plusieurs formats, voici comment j'ai procédé.
    Tout d'abord j'ai 2 classes distinctes VertexBuffer et IndexBuffer (qui pourraient facilement fusionner en un BufferBase, mais j'ai préféré les laisser séparés pour plusieurs raisons).
    Mais la principale différence avec le Yes::Engine réside dans la création et l'application des buffers. J'ai avant tout rajouté un enum dans la classe VertexBuffer définit comme ça :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
     
    enum { FORMAT_END, FORMAT_POSITION, FORMAT_NORMAL, FORMAT_COLOR0, FORMAT_COLOR1, FORMAT_TEXCOORD0, FORMAT_TEXCOORD1, FORMAT_TEXCOORD2, FORMAT_TEXCOORD3, FORMAT_TEXCOORD4, FORMAT_TEXCOORD5, FORMAT_TEXCOORD6, FORMAT_TEXCOORD7 };
    Ensuite, l'équivalent de ma fonction CreateVertexBuffer prend 1 paramètre supplémentaire qui est le format. C'est un simple tableau d'entiers qui décrit les composantes d'un Vertex, terminé par 0 (ou FORMAT_END). Voici un exemple simple :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
     
    struct Vertex { float x, y, z; float nx, ny, nz; };
    int VertexFormat[] =  {VertexBuffer::FORMAT_POSITION, VertexBuffer::FORMAT_NORMAL, 0 };
    Au moment de la création du VertexBuffer, je peux ainsi stocker ce format et compter la taille d'un Vertex. Une autre solution plus optimisée serait un simple entier pour définir le format, et dont chaque bit correspondrait à une composante (je compte transformer mon code dans ce sens bientôt).

    Maintenant que nous avons la taille d'un Vertex et l'ordre des composantes (donc le décalage de chaque composante par rapport au début du Vertex), il devient facile de créer le FVF sous DirectX ou d'appeler gl*Pointer avec les bonnes valeurs sous OpenGL.

    On remarquera qu'avec ce système, on est limité à un seul format par buffer (c'est une des limites de cette méthode), mais on manipule les fonctions en nombre de Vertex et non en taille (plus facile au moment de l'utilisation).
    Il faut également faire attention à l'ordre des composantes sous DirectX (car les FVF ne sont pas ordonnés), mais utiliser un champs de bits plutôt qu'une liste d'entiers limiterait à utiliser le même ordre sous DirectX en OpenGL.

    Enfin, on peut utiliser le même principe (plus simplement) avec les IndexBuffer pour pouvoir utiliser des int ou des short int au choix.

    Voilà, je ne sais pas trop si ça t'aide (je ne sais même pas si je suis assez clair), mais ça marche plutôt bien ^^.
    Si t'as besoin de morceaux de code supplémentaires, demande moi.

    Dummy

  3. #3
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    Salut Dummy !

    Merci pour ta réponse, j'ai un peu regardé comment tu as fait mais j'ai pas encore tout a fait compris. Je vais regarder ça de plus près ce week end. On m'a aussi donné depuis ce lien qui traite spécifiquement des formats de vertex:

    Sylvain.Lefebvre :GPUmesh
    .

    Bonne soirée,
    Tib0000

  4. #4
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    Salut,

    Désolé de upper ce topic mais j'ai trouvé récemment une "technique" basée sur des templates vraiment très très élégantes, qui te permet de faire des trucs comme ça :

    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    1
    2
    3
    4
    5
    6
    7
    typedef VertexComposer<Position<VertexComposer<Normal> > P3V3 // Position + Normales
     
    typedef VertexComposer<Position<VertexComposer<TexCoord> > P3T2 // Position + TexCoords 1
     
    typedef VertexComposer<Position<VertexComposer<Normal, VertexComposer<TexCoord, VertexComposer<TexCoord> > > > P3N3T2T2 // Position + Normales + TexCoords1 + TexCoords2
     
    ...
    Le code source est dispo sur Internet : http://www.gdmag.com/src/oct03.zip

    Et c'est le sous-fichier Cantlays.

    Bonnes fêtes.

  5. #5
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    C'est juste une implémentation moins générique des listes de types et des hiérarchies automatiques (décrites dans de livre "C++ modern Design" et utilisées dans la bibliothèque Loki)

    A part ça, je ne pense pas que cela résolve le problème original, qui est d'utiliser des formats de sommet non connus à la compilation (par exemple, uniquement au chargement du modèle).

  6. #6
    Rédacteur
    Avatar de Bakura
    Homme Profil pro
    Étudiant
    Inscrit en
    Septembre 2005
    Messages
    1 386
    Détails du profil
    Informations personnelles :
    Sexe : Homme
    Âge : 34
    Localisation : France, Val de Marne (Île de France)

    Informations professionnelles :
    Activité : Étudiant

    Informations forums :
    Inscription : Septembre 2005
    Messages : 1 386
    Points : 2 640
    Points
    2 640
    Par défaut
    A part ça, je ne pense pas que cela résolve le problème original, qui est d'utiliser des formats de sommet non connus à la compilation (par exemple, uniquement au chargement du modèle).
    Justement, je me posais cette question, en y regardant de plus près. Même si cette technique est ma foi très élégante, comment s'en servir de manière relativement propre, dans les cas où, comme tu dis, on charge un modèle et on ne sait pas à l'avance s'il n'a qu'une ou deux textures ?

    Dans quels cas est-ce utile ?

  7. #7
    Rédacteur
    Avatar de Laurent Gomila
    Profil pro
    Développeur informatique
    Inscrit en
    Avril 2003
    Messages
    10 651
    Détails du profil
    Informations personnelles :
    Âge : 39
    Localisation : France, Moselle (Lorraine)

    Informations professionnelles :
    Activité : Développeur informatique

    Informations forums :
    Inscription : Avril 2003
    Messages : 10 651
    Points : 15 920
    Points
    15 920
    Par défaut
    A mon avis c'est inutile, et donc un mauvais choix pour une application 3D qui se veut un minimum générique. Le fait est qu'au final, le niveau d'abstraction fait qu'on ne peut jamais hard-coder les composantes des sommets. Il vaut mieux privilégier une approche où l'on peut les spécifier dynamiquement.

  8. #8
    Futur Membre du Club
    Profil pro
    Inscrit en
    Octobre 2007
    Messages
    15
    Détails du profil
    Informations personnelles :
    Localisation : France

    Informations forums :
    Inscription : Octobre 2007
    Messages : 15
    Points : 6
    Points
    6
    Par défaut
    Désolé de re-upper le sujet, j'avais laissé tomber pour un moment le sujet étant hors de ma portée, mais je me suis récement remis à cette idée. je me permets donc de répondre à ta question, du moins comment je l'ai traitée.

    Pour rappeler, Sylvain Lefebvre utilise (via la bibliothèque loki) un typelist représentatif du format de vertex, du style :
    Code : Sélectionner tout - Visualiser dans une fenêtre à part
    typedef TYPELIST_2(Renderer::vertex3f, Renderer::normal3f) Pos3fNorm3f;
    .
    Ce format de vertex est utilisé par le vertex buffer dans les fonctions glVertexPointer, glNormalPointer ... pour retrouver rapidement et proprement le nombre de coordonnées, le type de donnée et l'emplacement dans le buffer du premier élément du tableau de données.

    Effectivement, cette solution n'est pas vraiment générique dans le sens ou il faut un type de format de vertex par modèle. Au début ça peut sembler "bourrin" mais dans mon cas je n'ai pas tant que ça de modèles, tout au plus dix (je doute d'ailleurs qu'il y en beaucoup dans un moteur pro) .

    Afin de réduire considérablement le nombre de possibilité, j'ai émis la condition que les buffers de données étaient toujours ordonnés dans le même sens: position, normal, couleur 0 et 1, texture 0 à 7 et attributs de 0 à 7. J'ai par ailleurs associé au modele chargé un identifaint unique représentant le format de vertex (ca peut être un enum), j'utilise pour ma part un string qui est construit lors de la création du buffer.

    J'ai une classe BaseRenderer<VertexFormat> contenant le vertex buffer, l'index buffer et les fondtions de rendu, release ... , template du format de vertex et qui dérive d'une classe IBaseRenderer. Ainsi qu'une classe Renderer qui "manage" les renderers de base (elle possède les méthodes Render, Release et AddOject) via une map associant les précédents string de format de vertex aux IBaseRenderer.

    Au final, à la création, je créé un objet BaseRenderer<VertexFormat> (que j'ajoute à la map) si l'objet n'existe pas et je lui ajoute le modèle, sinon j'ajoute directement le modèle.
    Pour le rendu, je rend tous les BaseRenderer de ma map. Pareil pour le release.

Discussions similaires

  1. Réponses: 4
    Dernier message: 08/03/2007, 10h32
  2. Memory Leaks in MemoryManager Yes engine
    Par couet dans le forum C++
    Réponses: 6
    Dernier message: 16/02/2007, 14h39
  3. error LNK2001 - YES::Engine
    Par gtelmon dans le forum VC++ .NET
    Réponses: 1
    Dernier message: 24/09/2006, 17h34
  4. pb de link dans Visual C++ avec yes engine
    Par Jabrul dans le forum MFC
    Réponses: 14
    Dernier message: 14/01/2006, 12h53
  5. Réponses: 11
    Dernier message: 21/09/2005, 03h56

Partager

Partager
  • Envoyer la discussion sur Viadeo
  • Envoyer la discussion sur Twitter
  • Envoyer la discussion sur Google
  • Envoyer la discussion sur Facebook
  • Envoyer la discussion sur Digg
  • Envoyer la discussion sur Delicious
  • Envoyer la discussion sur MySpace
  • Envoyer la discussion sur Yahoo