Supposons que je dessine une scène 3D glDrawArrays(...)
et que je souhaite rendre quelque chose de simple, comme une superposition 2D. Serait-ce une mauvaise idée d'utiliser le mode immédiat pour une telle chose, au lieu de configurer un rendu 2D avec le mode conservé?
Exemple:
void Draw()
{
// Draw the 3D scene:
// *does stuff*
glDrawArrays(...);
// *some other stuff*
// Setup a quad with immediate mode (for something like a vignette overlay)
glBegin(GL_QUADS);
glTexCoord2f(...); glVertex2f(...);
glEnd();
}
Réponses:
C'est une mauvaise idée dans la mesure où elle est absurde. Il n'y a rien à "configurer" que vous n'ayez pas déjà fait, à part une matrice de projection ortho (que vous devrez faire de toute façon).
La portabilité n'est probablement pas un problème, bien qu'elle devrait l'être. Les IHV semblent très réticents à abandonner la prise en charge du mode immédiat dans un avenir prévisible (il semble "fonctionner correctement" même dans les profils de base), donc bien que le mode immédiat ait dû disparaître il y a longtemps, il restera probablement pour toujours. La performance est une autre histoire. Voulez-vous vraiment que quelque chose qui représente 0,1% de la complexité de la scène consomme 15 à 20% du temps CPU - les appels GL sont relativement légers, par exemple DX, mais ils ne sont pas gratuits - et 15 à 20% des temps réel de trame dû au blocage du pipeline? Pouvez-vous même vous le permettre avec votre budget temps? La plupart des jeux ne le peuvent pas.
Et puis bien sûr, les bizarreries. Oh les bizarreries. La beauté apparente du mode immédiat est qu'il est (apparemment) facile et direct de faire quelque chose comme dessiner rapidement quelques quads. En réalité, le mode immédiat peut être une telle douleur à l'arrière, il est tellement plein d'embûches non évidentes.
D'un autre côté, il est tout aussi facile (et plus simple si vous me le demandez!) D'écrire simplement une petite fonction 5-LOC
DrawQuad
qui, lorsqu'elle est appelée, ajoute des coordonnées de sommet et des index dans un tampon de mémoire et incrémente un compteur. Avec qui, surprise, vous pouvez ensuite dessinerglDrawArrays/Elements
et que vous pouvez réutiliser (la copie GPU, pas seulement la copie utilisateur!) La prochaine image telle quelle tant que rien n'est changé.Le mode immédiat doit, il n'y a pas d'autre moyen, allouer un tampon et effectuer un transfert PCIe à chaque fois. Ou, quelque chose d'équivalent en latence (GPU lisant la mémoire principale sur le bus, peu importe). Le pilote ne peut pas savoir (ou supposer) que les données sont restées exactement les mêmes que l'image précédente.
Le transfert de données vers le GPU est une opération à grande vitesse, mais aussi à latence élevée . Non seulement le transfert de bus en soi est un protocole compliqué à latence élevée (plusieurs couches de protocole, mise en paquets, accusés de réception, etc.), mais tous les GPU ne sont même pas capables de transférer et de dessiner en même temps, ou s'ils peuvent le faire , ils peuvent ne pas être en mesure à tout moment de basculer entre ou de lancer de nouvelles opérations librement tout en faisant quelque chose de différent. Lire comme suit : Tu ne transféreras pas en vain .
la source
intel
pilote), mais aussi les puces NVidia et AMD lors de l'utilisation de pilotes open source (nouveau
etamdgpu
respectivement). De même, sur MacOS, vous n'avez pas non plus de profil de compatibilité avec OpenGL> 2.1.glDrawArrays
. Il y a donc tout mis en place qui est nécessaire pour faire encore un autre appel àglDrawElements
(ou Array, selon le cas) pour dessiner tous les quads pour l'interface graphique (après avoir écrit les sommets dans un tampon). Les fonctions sont chargées, vous avez un cadre pour l'allocation de tampons, etc. Rien de spécial à faire pour le traitement par lots de l'interface graphique, vraiment. Liez simplement (ou non, s'il vous reste suffisamment de TU pour le laisser lié) la texture de l'interface graphique, définissez la matrice ortho et effectuez un appel de dessin supplémentaire. Comment voulez-vous mieux loter?Personnellement, je ne le vois que comme mauvais pour deux raisons:
Mais, si cela fonctionne, et que les performances ne seront pas un problème, et si ce n'est pas un problème pour vous d'utiliser des fonctions OpenGL obsolètes dans votre programme, je pense que vous pouvez le faire. Il sera plus lent d'avoir des tonnes et des tonnes d'interfaces graphiques, mais si ce n'est pas beaucoup, encore une fois, allez-y.
Mais comprenez cela. Qu'à la fin de la journée, OpenGL fait la même chose; dessin à l'écran. Le mode immédiat est beaucoup plus lent si vous avez beaucoup de choses en cours de traitement. Vous devez donc choisir ce qui est le plus utile pour la tâche que vous avez en tête. J'espère que cela vous aide!
la source
Un autre inconvénient est qu'il rend votre code moins portable. Certaines variantes OpenGL ne prennent pas du tout en charge le mode immédiat, par exemple OpenGL ES. (et comme les appareils Android de plus gros calibre tels que les tablettes gagnent en traction, cela pourrait devenir important)
la source
L'utilisation du mode immédiat n'est absolument pas nécessaire pour le travail lié à l'interface graphique.
Pour créer un simple élément graphique, disons un bouton:
De cette façon, vous pouvez simplement écrire un shader d'intercommunication simple qui ignore les considérations d'éclairage, et vous mettez simplement à l'échelle l'élément gui à une échelle de pixels, ou un certain pourcentage de la fenêtre, puis effectuez un algorithme de peinture pour le rendu.
De cette façon, vous pouvez faire un système d'interface utilisateur complet avec tous les avantages de performance du mode conservé.
la source