Dans OpenGL, est-ce une mauvaise idée de «combiner» le mode immédiat et le mode retenu pour le bien des interfaces graphiques?

8

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();
}
KK Slider
la source
Minecraft le fait. Cela fonctionne très bien, sauf pour limiter votre version d'OpenGL (à <3.1 ou un profil de compatibilité) et pour rendre votre interface graphique moins rapide.
user253751
Remarque Minecraft a également son propre ensemble de fonctions qui simulent le mode immédiat à l'aide de tableaux de sommets - ce n'est pas difficile à écrire. Je ne sais pas encore s'ils les utilisent pour l'interface graphique.
user253751

Réponses:

7

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 DrawQuadqui, 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 dessiner glDrawArrays/Elementset 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 .

Damon
la source
"Il n'y a rien à" configurer "que vous n'ayez pas déjà fait" Rendu batch?
HolyBlackCat
2
Bien que les IHV hésitent à abandonner le mode immédiat, il existe également des pilotes vidéo sous Linux qui ne prennent pas en charge la version OpenGL supérieure, sauf si vous demandez le profil principal. Cela signifie en particulier les graphiques Intel HD ( intelpilote), mais aussi les puces NVidia et AMD lors de l'utilisation de pilotes open source ( nouveauet amdgpurespectivement). De même, sur MacOS, vous n'avez pas non plus de profil de compatibilité avec OpenGL> 2.1.
Ruslan
@HolyBlackCat: Je ne sais pas ce que tu veux dire? OP indique avoir un pipeline 3D fonctionnel basé sur 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?
Damon
(Bien sûr, je suis d'accord que le mode immédiat est mauvais.) Désolé si je n'ai pas été clair. Je veux dire le processus de remplissage dudit tampon de vertex. C'est facile, mais c'est un peu plus de travail qu'en utilisant le mode immédiat.
HolyBlackCat
12

Personnellement, je ne le vois que comme mauvais pour deux raisons:

  1. Il est très obsolète et obsolète. Et,
  2. C'est beaucoup plus lent que les méthodes modernes de dessin avec OpenGL.

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!

dev9999
la source
1

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)

Afficher un nom
la source
0

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:

  1. Vous avez besoin d'un maillage de bande quad / triangle,
  2. Une texture pour le maillage
  3. Une transformation de projection orthographique

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é.

Ian Young
la source