8
votes

Comment garder une trace de OpenGL State à travers les appels de fonction?

Puisque OpenGL est une machine à états, je suis constamment glenable () et gldisable () des choses dans mon programme. Il y a quelques appels Sélectionnez quelques appels que je ne fais que au début (comme GlclearColor), mais la plupart des autres, je retourne et éteint (comme l'éclairage, en fonction de si je rends un modèle ou un texte 3D ou l'interface graphique).

Comment gardez-vous une trace de l'état des choses? Avez-vous constamment défini / réinitialiser ces choses en haut de chaque fonction? N'est-ce pas beaucoup de frais généraux inutiles?

Par exemple, lorsque j'écris une nouvelle fonction, je sais parfois quelles éléments d'état seront dans la fonction lorsque la fonction est appelée, et que je laisse de côté glenable ou gldisable ou d'autres appels de commutation d'état connexes en haut de la fonction. D'autres fois, je suis juste en train d'écrire la fonction à l'avance et j'ajouterai ces types de choses. Donc, mes fonctions finissent par être très désordonnée, certaines d'entre elles modifiant l'état OpenGL et d'autres qui font des hypothèses (qui sont plus tard cassées, puis je dois revenir en arrière et comprendre pourquoi quelque chose devenu jaune ou pourquoi une autre chose est à l'envers, etc. ).

Comment gardez-vous une trace de OpenGL à travers les fonctions dans un environnement orienté objet?


Également lié à cette question, est comment savoir quand utiliser Push and Pop, et quand il suffit de définir la valeur.

Par exemple, disons que vous avez un programme qui dessine des trucs 3D, puis dessine des trucs 2D. Évidemment, la matrice de projection est différente dans chaque cas. Alors avez-vous:

  1. Configurez une matrice de projection 3D, dessinez 3D, configurez une matrice de projection 2D, dessinez 2D, boucle
  2. Configurez une matrice de projection 3D au programme; Puis dessinez 3D, poussoir matrice, dessinez 2D, matrice pop, boucle

    et pourquoi?


0 commentaires

3 Réponses :


2
votes

Grande question. Pensez à la façon dont les textures fonctionnent. Il existe une quantité insensée de textures pour OpenGL pour basculer entre, et vous devez activer / désactiver la texturation après chaque objet est tiré. Vous essayez généralement d'optimiser cela en tirant à la fois tous les objets avec la même texture, mais il existe toujours une quantité remarquable de commutation d'état qui se passe. En raison de ce fait, je fais de mon mieux pour tout attirer avec le même État à la fois, mais je ne suis pas sûr que s'il est terriblement important d'optimiser la façon dont vous pensez.

En ce qui concerne la poussée et la poussée entre les modes de projection 3D et 2D, poussoir et apparaissant est destiné à être utilisé pour la modélisation hiérarchique. Si vous avez besoin de votre projection 2D pour être à un emplacement par rapport à un objet 3D, appuyez sur la matrice et le commutateur en mode de projection 2D, puis pop lorsque vous avez terminé. Cependant, si vous écrivez une superposition d'interface graphique 2D qui a un emplacement constant à l'écran, je ne vois aucune raison pour que la poussée et la sautilation est importante.


1 commentaires

Eh bien, je ne suis pas sûr que votre premier paragraphe traite vraiment de la question, bien que je suis sûr que c'est en grande partie parce que je ne me l'explique pas assez bien. J'ai besoin de revenir à cette question lorsque j'ai une idée plus claire d'exactement ce que j'essaie de demander. Merci pour l'aperçu de la poussée / pop cependant, j'aime cette explication.



2
votes

Vous pourriez être intéressé de lire davantage sur les bibliothèques de graphique de la scène. Ils sont destinés à gérer vos graphiques à partir d'un niveau supérieur. Ils ne manipulent pas tout bien, mais ils excellent à organiser votre géométrie pour un rendu optimisé. Ils peuvent également être utilisés pour trier vos scènes basées sur l'état OpenGL, bien que beaucoup ne le font pas. En triant sur l'état, vous pouvez rendre votre géométrie dans une commande qui entraîne moins de transitions de l'état. Voici une vue d'ensemble des bibliothèques de graphique de la scène:

http://www.realityprime.com/articles/scenegraphes -past-présent-and-futur


3 commentaires

Oui, je connais très bien avec eux. J'utilise Java, alors il y a Xith3d et JmonkeyEngine. Le problème était que je suis obsédé par ces moteurs et que je n'ai rien fait de valeur. Maintenant que j'ai juste écrit Pure OpenGL, je reçois en fait des choses. Merci quand même.


Il semble que vous réintroduisez un peu la roue. Combien de ce que vous avez accompli était déjà géré par une bibliothèque de graphes de scène?


Chargeur de fichier .ms3D avec calcul de la boîte de sélection. C'est probablement à ce sujet. Ce que je ne peux pas faire avec une bibliothèque de graphique de scène, au moins facilement, ma Hauteur Special HeightMap (avec chargement dynamique planifié) et mes fonctionnalités de GUI personnalisées. Alors oui, c'est un compromis, mais c'est plus facile pour moi d'écrire les choses qu'une bibliothèque de graphique de scène peut faire et ensuite faire d'autres choses qu'elle ne peut pas, plutôt que d'utiliser une seule et d'essayer de comprendre les solutions de contournement et des hacks juste pour pouvoir dessiner Formes 2D sur l'écran ou quelque chose.



2
votes

Je pense que l'approche la plus simple serait d'écrire votre propre classe de rendu, d'envelopper toutes les fonctions de manipulation de l'état OpenGL que vous utilisez et que vous réservez la conservation des états que vous avez définis. Vous devez prendre en compte la modification de la résolution de l'écran ou de basculer le mode plein écran d'écran invalidera vos états et données de contexte actuels OpenGL Render, ce qui signifie qu'après un tel événement, vous devrez définir tous les états, rétablier toutes les textures et les programmes de textures et de shader, etc. .


0 commentaires