Bonjour à tous,
J'apprends actuellement à développer avec OpenGL via différents tutoriaux à droite et à gauche (notamment ceux de ce site), et je dois dire que je suis plutôt content de ce que j'arrive à faire jusque là.
Néanmoins, pour avancer correctement, je souhaiterais en savoir plus sur l'organisation de mon code dans le cadre d'un projet simple mais assez vaste, permettant concaténer l'ensemble des manipulations que fournissent les cours sur lesquels je me base.
Mon manager de fenêtre est "SFML"
Aujourd'hui, j'ai pu scinder mon code en différentes parties qui me semblent relativement juste, et qui se répartissent les rôles comme suivant :
- Main : ne fait rien de spécial si ce n'est instancier et appeler une classe contenant mon manager de fenêtre ainsi que la boucle principale
- Manager : ici, je configure SFML et ouvre ma fenêtre, lance la boucle principale dans un thread (l'affichage se fait dans ce thread), et continue sur le gestionnaire d'événements (gestion du clavier) dans un autre thread. C'est aussi dans cette classe que je j'instancie les différents objets à afficher
- solid : le nom n'est peut être pas explicite, mais en gros, c'est la classe "objet" qui défini le comportement d'un objet au sein de mon environnement, comment ce dernier doit agir, gère sa position et les différentes matrices de transformation qui lui sont appliquées etc... Le but final étant de transformer, à terme, cette classe en classe "mère" des différents objets à afficher. Les objets de classe "solid" possèdent un modèle
- shader : une classe assez simple, permettant de compiler et linker les vertex shaders ainsi que les fragment shaders, et permettant de retourner l'identifiant du programme compilé. Un objet de classe "shader" est instancié dans la classe model ; les codes glsl sont donc chargés et compilés à chaque instanciation d'un modèle...
- model : nom assez explicite, mais c'est pour cette dernière que je me pose le plus de questions quant à son contenu. A ce jour, les coordonnées des vertex sont codés en dur, mais c'est cette classe qui, dans un avenir proche je l'espère, sera capable de charger les modèles et textures associées. A chaque instanciation, chaque objet compile les shaders, génère les buffers, les bind, leur envoie les data etc... On y retrouve aussi une fonction membre draw(), qui permet l'affichage du modèle à chaque appel (où l'on y retrouve le glDrawElements())
- camera : je commence à peine à me pencher sur ce sujet, et il me semble pertinent d'avoir une classe dédiée pour configurer et piloter la caméra (on y retrouve donc les glm::lookAt et glm::perspective)
Ma question est donc la suivante : est-ce vraiment à la classe model de gérer les "Vertex Buffer Object", Element Buffer Object" ou encore les "Vertex Array Objects" ? Car j'ai remarqué que, lorsque j'affiche deux objets différents, le premier modèle est affecté par l'affectation d'un "uniform" (la couleur par exemple) sur le second modèle... J'en déduis donc que, malgré une compilation des shader par instanciation, les ID du programme sont partagés ! J'ai pu aisément contourner cette contrainte, mais si c'est souhaitable, je préfère réorienter mon code maintenant que lorsqu'il sera plus complexe.
Sinon, où puis-je trouver un tutoriel dans lequel quelques classes minimalistes illustrent une des organisation possible du code ? Sur tous les code que j'ai pu voir jusqu'à maintenant, pour des raison de commodité je pense, tous sont présentés en bloc dans le main.
Merci d'avance !
Petite démonstration du résultat actuel (sachant que le tétraèdre rouge tourne sur lui-même et est en couleur "remplie" par défaut) :
Partager