GFX coding - Part 5 - OpenGL / Direct3D


Cette partie a pour objectif de montrer les points communs (et les différences...) entre les 2 API reines au pays de la 3D temps réel. Il n'est pas question de dire si l'une ou l'autre est mieux, ceci n'ayant pas de sens d'ailleurs. Ce ne sont que des outils pour transformer notre immagination en quelque chose de visible à l'écran. Utiliser une API plutôt qu'une autre est juste une question de feeling et peut être aussi de contrainte technique (pour développer une application 3D sous Unix par exemple.). Personnellement je préfère OpenGL pour sa simplicité et Direct3D pour sa rapidité... Sur ce, bon coding.
JeGX


Tutorial 01
Affichage d'un triangle en gouraud.
Author : JeGX

tutorial 01 OpenGL VC++ Project
Author : JeGX

tutorial 01 Direct3D VC++ Project
Analyse:
  • En mode release, l'exe opengl fait 32 ko, celui de d3d 108ko.
  • Sur ma puce GeForce 2 Ultra (sous win2k sp2, derniers drivers nvidia 29.42)la qualité du rendu opengl est supérieur de loin a celui de direct3d. Pourquoi? Est ce un probleme de driver au niveau d3d???
  • Coté code, on retrouve les memes groupes de fonctions avec un net penchantvers la complexité pour direct3d (vu que c'est basé sur COM, on aurait pus'en douter.)


  • Tutorial 02
    Affichage d'un mesh en fil de fer.
    Author : JeGX

    tutorial 02 OpenGL VC++ Project
    Author : JeGX

    tutorial 02 Direct3D VC++ Project
    Analyse:
  • L'indexBuffer de d3d utilise des WORD (16 bits) pour stocker les index des vertices pour chaque face. Ce qui signifie que l'on ne peut avoir un mesh unique avec plus de 65536 vertices. C'est clair que cela fait deja un meshbalaise mais quand meme, pourquoi une telle limitation? Que ce soit avecles display list ou les vertexbuffer, il n'y a pas cette limitation en ogl.
  • ogl permet une affectation dynamique des couleurs pour l'ensemble des vertices d'un mesh. Avec d3d, c'est le contraire. L'affectation est statiqueet il faut reparcourir tout le tableau des vertices pour changer la couleurde ces derniers. Il n'y a pas de notion de couleur active en d3d.
  • Pour les meshes volumineux, il faut absolument passer un vertex/indexBuffer en ogl. Les display list sont beaucoup trop lentes (cas du torus en fil defer avec 19200 polygones) : 65 fps avec vertex/indexBuffer et 22 fps avecles display list. Quand a d3d, c'est 33 fps avec vertex/indexBuffer.OpenGL est bien rapide... en wireframe.


  • Tutorial 03
    Affichage d'un mesh avec lighting.
    Author : JeGX

    tutorial 03 OpenGL VC++ Project
    Author : JeGX

    tutorial 03 Direct3D VC++ Project
    Analyse:
    Coup de théatre : d3d l'emporte haut la main sur ogl en terme de vitesse dèsque l'on active l'éclairage!!! Pour le torus de 19200 faces, d3d le fait tourner à près de 48 fps tandis que ogl 15 fps. Quelle chute! D'ou vient une telle différence? Les puces GeForce seraient-elles hyper optimisées pour Direct3D??? Ca m'en a tout l'air...

    Voir la réponse à ces questions dans le tutor 11.


    Tutorial 04
    Affichage d'un mesh en avec texturing.
    Author : JeGX

    tutorial 04 OpenGL VC++ Project
    Author : JeGX

    tutorial 04 Direct3D VC++ Project
    Analyse:
    Rien de particulier. La aussi d3d est plus rapide qu'ogl!On retrouve toujours les groupes de fonctions équivalents.


    Tutorial 05
    Affichage d'un mesh en avec texturing et lighting.
    Author : JeGX

    tutorial 05 OpenGL VC++ Project
    Author : JeGX

    tutorial 05 Direct3D VC++ Project
    Analyse:
    Décidement d3d toujours plus rapide qu'ogl! Mais dans ce cas la, ogl est carrément plus lent car pour reproduire la mêne scène (a savoir le toretexturé avec les reflets spéculaires), il faut dessiner 2 fois le tore avecogl, une fois texturé et la 2eme fois sans texture mais en activant l'éclairage.Ici d3d est supérieur quand a la facon d'opérer : tout se fait en seule passe grâceaux unités de texture : on peut combiner 2 types d'entrées (texture et lighting) :m_pd3dDevice->SetTextureStageState( 0, D3DTSS_COLOROP, D3DTOP_MODULATE );et l'unité de texture combine les 2 entrées pour générer une sortie (qui elle mêmepeut servir d'entrée a une nouvelle unité de texture...). Avec ogl on peut aussi faire du texturing et du lighting en une passe grâce à :glTexEnvi( GL_TEXTURE_ENV, GL_TEXTURE_ENV_MODE, GL_MODULATE );mais les reflets spéculaires sont quasi-inexistants...


    Tutorial 06
    Affichage d'un mesh en avec texturing et lighting - Chargement d'un fichier PMF.
    Author : JeGX

    tutorial 06 Direct3D VC++ Project
    Analyse:
    Ce tutorial n'est dispo qu'en d3d car c'est pour montrer le loading d'un PMF (Precompiled Mesh File). Il n'y aucune nouveauté au niveau 3D.Le fichier PMF contient toutes les information d'un mesh : sommets 3d, faces, coordonnées de texture et nouveauté et c'est ce qui est intéressant, il contient aussi toutes les normales (vertex normal et face normal) deja précalculées. Le chargement d'un tore a 20000 faces prend 1 seconde avec le PMF et environ 10 a 15 secondes avec le ASC classique. Autre intérêt : il est 2 fois plus petit qu son homologue ASC...La version 3 du format PMF comporte les bounding box et sphere du mesh 3d. C'est utile pour le calcul des collisions entre autre...

    Documentation de référence du format PMF: Precompiled Mesh File v3 Et voila un peti convertisseur format 3DS vers PMF version 3: 3ds2pmf converter binary


    Tutorial 07
    Blending et texturing - Remplissages des vertexBuffer à la main
    Author : JeGX

    tutorial 07 OpenGL VC++ Project
    Author : JeGX

    tutorial 07 Direct3D VC++ Project
    Analyse:
    Ce tutorial, l'air de rien, m'a donné du fil à retordre au niveau de Direct3D.Après quelques heures de combat contre la machine, j'ai vaincu finalement, et j'ai pu mettre en oeuvre le blending et plus particulièrement l'effet de transparence. Et oui, c'est Direct3D! Je ne sais pas pourquoi, mais même si D3D est un peu plus compliqué à utiliser, je commence à l'apprécier. On a en effet un contrôle vraiment plus précis sur le pipeline 3d ce qui implique forcément un surplus de complexité mais bon, on n'est plus à ca près quand on fait de la 3D... Et toujours cette rapidité de rendu... J'ai introduis la notion de shader en général (non pas encore les vertex et pixel shader, ca c'est pour bientôt). Je définis un shader comme un object (au sens immatériel) qui détermine l'apparence de la surface d'un objet (cette fois ci matériel, mesh 3d).J'ai donc créé une méthode s'appellant setCubeShader() qui contient le code pour donner la transparence et l'application de texture sur le cube éclaté. Les codes sources sont comme d'habitude assez commentés donc on retrouvera sans problème les portions de codes ad hoc.


    Tutorial 08
    Multitexturing et lightmapping
    Author : JeGX

    tutorial 08 OpenGL VC++ Project
    Author : JeGX

    tutorial 08 Direct3D VC++ Project
    Analyse:
    Le mutltitexturing ne fait pas partie de l'API de base d'OpenGL. Il est présent en tant qu'extension officielle (ARB). L'utilisation est des plus simples: la fonction glMultiTexCoord2fARB() remplace tout simplement la fonction glTexCoord2f(). Coté Direct3D, le multitexturing est une chose innée grâce aux texture stage. Un texture stage est un module qui effectue une opération sur 2 entrées pour fournir une sortie. Et les sorties peuvent servir d'entrées... Pour faire du multitexturing avec 2 textures, on utilise 2 texture stage chacun étant paramétré avec une texture, la sortie du premier stage servant d'entrée au second. Et c'est tout! L'effet dynamique (pour faire du lightmapping) est fait simplement en faisant varier la coordonnée de texture u de la seconde texture, que ce soit avec OpenGL ou Direct3D. La petite difficulté avec Direct3D a été de définir correctement la structure du custom vertex...

    ThanX au site de Nehe (http://nehe.gamedev.net) et au tutorial 22.


    Tutorial 09
    Stencil Buffer et Viewport
    Author : JeGX

    tutorial 09 OpenGL VC++ Project
    Author : JeGX

    tutorial 09 Direct3D VC++ Project
    Analyse:
    Le stencil buffer est vraiment un outil efficace pour le developpeur 3D. Il est assez simple à mettre en oeuvre (les fonctions sont quasiment identiques avec OpenGL et Direct3D) et à comprendre dans les cas classiques où l'on doit limiter la surface de rendue. Malgrès tout, j'ai passé quand même un certain temps avant que le code ne marche à cause de l'initialisation du stencil buffer dans les contextes de rendu (structure PIXELFORMATDESCRIPTOR pour OpenGL par exemple) que j'avais complètement oublié! Et en général ca foire toujours aux petites heures du matin (e si ho fatto le ore piccole per questi tutori!!!) ce qui complique la tâche de debug... Ce que j'adore avec D3D, c'est le contrôle que l'on a sur le pipeline 3D. Par exemple (exemple pertinant mon cher!) il existe des formats de vertex non transformés (les seuls que connais OpenGL) et des formats de vertex transformés. Les vertex transformés sont les vertex (vertices je sais!) issus du module T&L et destinés au rasterizer. Tout ça pour dire que sans spécifier de projection ortho, on directement faire de la 2D (afficher le quad de la cible par exemple) et donc mélanger allégrement 2D/3D sans même sans rendre compte. Avec OpenGL, il faut obligatoirement préciser le type de projection (ortho pour de la 2d) et faire passer tout les vertex dans le pipeline 3d...

    L'idée de ce tutor m'est venu en lisant l'article sur le stencil buffer du livre "Real-Time Rendering Tricks and Techinques in DirectX" de Kelly Dempsky.


    Tutorial 10
    Spherical Environment Mapping and Stencil Buffer
    Author : JeGX

    tutorial 10 OpenGL VC++ Project
    Author : JeGX

    tutorial 10 Direct3D VC++ Project
    Analyse:
    Voila un petit tutor en hommage a Jan Horn. La nouveauté de ce tutor est le sphérical mapping. En gros, on laisse a OpenGL ou Direct3D le soin de calculer les coordonnées de textures selon la normale de chaque vertex du mesh 3d (genre u=(Nx/2)+0.5 et v=(Ny/2)+0.5) ce qui permet de simuler des effets de reflexions de l'environement de l'objet 3d. La mise en oeuvre est top simple que ce soit en OGL ou D3D. Visulellement, le résultat semble meilleur avec OpenGL (GeForce 4 Ti 4400 - drivers 30.82 et win2k sp3) mais avec toujours une vitesse infiniment supérieur pour D3D... Ici le stencil buffer permet de simulier un effet de détecteur à rayon X qui permet de voi le knot en fil de fer à l'endroit du viseur.

    The idea behind this tutor comes from Sulaco OpenGL site (http://www.sulaco.co.za) when i saw one of Jan's demos about stencil buffer. I found the concept easy and great!ThanX to this coooool site... e stia in pace dove sei amico mio.


    Tutorial 11
    OpenGL EXT_swap_control extension
    Author : JeGX

    tutorial 11 OpenGL VC++ Project
    Analyse:
    Mon travail sur le moteur oZone3D m'a permis, au cours d'une lecture, de trouver la façon de débrider OpenGL pour avoir des framerates comme Direct3D. Il faut tout simplement utiliser l'extension EXT_swap_control qui pilote la synchro verticale. Par défaut, OpenGL est synchronisé avec le rafraîchissement vertical donc si la fréquence verticale de la carte graphique est réglée sur 75Hz, alors le framerate d'une animation OGL ne dépassera jamais 75 FPS!!! Direct3D n'est pas calé, par défaut, sur la synchro verticale et du coup on a facilement des fPS astronomiques. Ici le tutor D3D n'est la que pour la comparaison. L'objet 3d a environ 1600 polygones. Le FPS de D3D est de 840. Celui d'OGL sans utilisation de l'extension est de 82 (ma carte graphique est réglée sur un fréquence verticale de 85Hz) Avec l'extension activée, le FPS d'OGL grimpe a 780... Direct3D est toujours plus rapide que OpenGL mais de très peu.


    Tutorial 12
    Alpha testing
    Author : JeGX

    tutorial 12 OpenGL VC++ Project
    Analyse:
    Pas grand chose à dire sinon que ca peut être une solution pratique pour simuler a faible cout des objets complexes...