31 January 2009

Développement d'une API 3D en C++: base des matériaux

Le développement de mon API C++ basée sur OpenGL suis son cours. Lors du dernier billet de la rubrique "Développement", j'avais présenté les différentes fonctionnalités possibles, et m'étais arrêté sur les vecteurs normaux permettant de diffuser correctement la lumière sur toute la géométrie des objets. Le matériau utilisé pour afficher les objets 3D, dans mon API, était jusqu'ici toujours le même: un gris moyen.

J'ai amélioré l'API afin de gérer les matériaux propres aux objets de type Wavefront. Ces matériaux sont stockés dans des fichiers d'extension .mtl (pour Material Library) et sont composés de plusieurs informations: la couleur ambiante du matériau, sa couleur diffuse, sa couleur spéculaire (renvoyée par la lumière) et l'intensité de la réflection de la lumière (directement liée à la couleur spéculaire). Oh, et la valeur du canal de transparence (alpha) est également lue, mais ce dernier n'est pas encore utilisé (l'Alpha Blending, c'est pour plus tard).

Concrètement, qu'est-ce qui change depuis la dernière version? Et bien, lorsqu'un objet est modélisé à l'aide de Blender, on peut naturellement lui attribuer une quelconque couleur ambiante, spéculaire et diffuse; lorsque l'objet sera exporté en Wavefront et chargé grâce à mon API, ces paramètres définis à l'aide de Blender seront restaurés. Dès lors, il m'est possible de développer une application comportant divers objets 3D où la lumière est prise en compte pour le rendu (shading) - ce qui était déjà le cas auparavant -, mais où les variations de couleurs définies le sont également.

Vous devez peut être vous en douter: la prochaine étape est la prise en charge des textures.

Wait & See !


Le verre de bière 3D est de retour !

Voici le grand retour tant attendu du verre de bière 3D, positionné dans un environnement plus coquet mettant davantage en valeur la réfraction de la lumière. Les plus malins auront remarqué qu'il s'agit d'une ancienne scène que j'avais déjà réalisée par le passé, à laquelle j'ai ajouté le fameux verre. De plus, j'ai appliqué une plus belle texture à la table et aux chaises. Au risque d'en décevoir certains, le verre est toujours vide !


15 January 2009

Le verre de bière 3D

Parmi les nombreux objets représentant un parfait exercice de modélisation, le verre est toujours une composition requérant de l'adresse, de la compétence et un peu d'originalité. Bien que la géométrie résultante de cette modélisation soit complexe, cette dernière ne le fut pas tant. En effet les verres, ainsi que tout objet circulaire dont les points sont équitablement et uniformément répartis autour d'un centre, sont faciles à créer grâce aux fonctions de Spin.

Pour créer ce verre, je l'ai tout d'abord dessiné de profil, et de moitié. En regardant le profil depuis une vue du dessus, on aperçoit ce dernier comme étant un simple tracé droit: c'est le rayon d'un cercle! En appliquant un Spin, ce rayon (et donc, ce profil) est dupliqué un nombre déterminé de fois, par rotation autour d'un axe, pour former un objet rond qui peut ensuite être affiné (Subsurf, Smooth).

Reste les caractéristiques de réfraction à spécifier, ceux-ci sont d'ailleurs souvent bien difficiles à définir, et de nombreux essais ont été nécessaires. D'ailleurs, sur ce rendu, j'ai volontairement désactivé les ombres portées, sans quoi je risquais bien de m'arracher les cheveux! Et oui, la modélisation s'apprend pas à pas.

Pour le choix du verre, je n'ai pu m'empêcher de penser à mes nombreux amis amateurs de bonnes bières belges. Pour un prochain rendu, promis, j'essaierai d'y mettre une belle blonde!


04 January 2009

Développement d'une API 3D en C++

Après avoir acquis les bases nécessaires à la modélisation d'objets et de scènes 3D sous Blender, je me suis tout naturellement tourné vers le développement. En effet, mon apprentissage de Blender n'a pour seul but de concrétiser la création de mes propres personnages, objets et niveaux en 3D en vue de les inclure dans un jeu vidéo ou toute autre application en trois dimensions. Il m'était donc indispensable d'appréhender le développement d'applications 3D. Pour ne pas commencer par un trop gros projet, j'ai entrepris la programmation d'une API (Application Programming Interface) me permettant de lire et charger facilement en mémoire des objets 3D, tout en fournissant bien entendu la possibilité d'afficher ceux-ci à l'écran, sous diverses coutures et en appliquant moults fonctionnalités.

Constat: cela faisait longtemps que je ne m'étais pas autant amusé à programmer ! J'ai sélectionné une arme de premier choix: le C++, version orientée objet et optimisée du très célèbre langage C. J'avais déjà fait un peu de C++ par le passé, mais j'étais rouillé. Aujourd'hui, grâce à mes travaux, j'ai pu réapprendre à programmer avec ce langage, et même à améliorer mes connaissances et compétences. A l'heure actuelle, je n'ai rencontré aucun obstacle que je n'ai pu franchir en m'appliquant correctement tout en lisant didacticiels et références. En ce qui concerne les aspects 3D, j'utilise l'API OpenGL, bien sûr, vu qu'il est libre et qu'il se marie très bien avec le C++. Mais c'est aussi parceque j'avais déjà un peu d'expérience dans le domaine, je dois bien l'avouer. Mes études universitaires n'y sont pas pour rien.

Alors, cette interface de programmation, que diable fait-elle? Le fait est qu'OpenGL fournit un ensemble de fonctionnalités et routines procédurales et pas vraiment orientées objet. Or, ce dernier paradigme est crucial pour tout bon développeur qui se respecte (et pour tout bon logiciel, soit dit en passant). Dès lors, je me suis attellé à la création d'une API fournissant diverses classes d'objet C++ permettant de gérer les aspects 3D d'un programme. Ainsi, j'ai conçu des objets Vertex, des Face, des VertexNormal, des ShadedFace ou encore des WFObject (objets 3D chargés à partir d'un fichier Wavefront, d'extension .obj). Concrètement, il est ainsi possible de représenter un mesh 3D à partir de ces objets. Chaque mesh est composé d'un nombre défini de points dans l'espace, appellés vertices (le pluriel de vertex). Quatre vertices peuvent représenter une face, et un grand nombre de faces assemblées les unes aux autres forment un objet en trois dimensions. Plus il y a de faces, plus l'objet possède une géométrie agréable à regarder et proche de la réalité. L'API que j'ai développée permet ainsi de mettre facilement en musique tout ces concepts, de lire toutes les données requises pour la création d'un objet dans un fichier, et d'afficher l'objet en 3D à l'écran par le simple appel d'une méthode nommée draw().

Suite à de nombreuses lignes de code (et de nombreuses heures), j'ai pu représenter des objets 3D construits à partir de faces à 3 ou 4 points. Ces faces possèdent également des normales (vecteurs directeurs) permettant de définir correctement la diffusion de la lumière sur l'objet (cf la photo de cet article). Je peux donc désormais charger dans une application 3D de ma création, tout objet 3D conçu par mes soins via Blender. Voici déjà un premier pas franchi vers la création de logiciels 3D avancés, comme par exemple... des jeux vidéo!

Les prochaines étapes du développement de cette API sont la prise en charge des matériaux associés à l'objet (couleur diffuse, spéculaire, degré de brillance, etc.) ainsi que des textures et leurs coordonnées. Ensuite, je compte définir des bounding boxes sur mes objets afin de définir les limites de leur volume dans l'espace, ce qui permet d'appliquer un algorithme de détection de collisions !

Stay tuned, comme on dit.