Question

Par défaut, il semble que les objets soient dessinés d'avant en arrière. Je dessine un objet d'interface utilisateur 2D et souhaite le créer de nouveau. Par exemple, je pourrais d'abord créer un carré blanc, puis créer un carré noir légèrement plus petit, créant ainsi un volet noir avec une bordure blanche. Ce message a donné lieu à une discussion et décrit cet ordre comme étant le " Algorithme du peintre " mais finalement, l'exemple qu'ils ont donné a simplement rendu les objets dans l'ordre inverse pour obtenir l'effet souhaité. Je retourne de haut en bas (les premiers objets remontent, les objets suivants sont dessinés en haut). Le rendu peut être obtenu via une transformation (gOrtho?)?

Je mentionnerai également que je ne suis pas intéressé par une solution utilisant une bibliothèque d'empaquetage telle que GLUT.

J'ai également constaté que le comportement par défaut sur le Mac utilisant Cocoa NSOpenGLView semblait revenir à l'avant-plan, où, comme dans les fenêtres, je ne peux pas obtenir ce comportement. Le code d'installation dans les fenêtres que j'utilise est le suivant:

glViewport (0, 0, wd, ht);
glMatrixMode(GL_PROJECTION);           
glLoadIdentity();                      
glOrtho (0.0f, wd, ht, 0.0f, -1.0f, 1.0f);
glMatrixMode(GL_MODELVIEW);             
glLoadIdentity();                       
Était-ce utile?

La solution

L'appel suivant désactivera les tests de profondeur, ce qui entraînera le dessin des objets dans l'ordre créé. Cela provoquera en effet un retour des objets vers l'avant.

glDepthFunc(GL_NEVER);      // Ignore depth values (Z) to cause drawing bottom to top

Assurez-vous de ne pas appeler ceci:

glEnable (GL_DEPTH_TEST);   // Enables Depth Testing

Autres conseils

En ce qui concerne votre question spécifique, non, il n’existe pas de moyen normalisé de spécifier un ordre de profondeur dans OpenGL. Certaines implémentations peuvent effectuer un ordre de profondeur allant de l'avant à l'arrière par défaut, car c'est généralement plus rapide, mais cela n'est pas garanti (comme vous l'avez découvert).

Mais je ne vois pas vraiment comment cela vous aidera dans votre scénario. Si vous tracez un carré noir devant un carré blanc, celui-ci doit être tracé devant le carré blanc, quel que soit l'ordre dans lequel ils sont dessinés, tant que la mise en mémoire tampon de la profondeur est activée. S'ils sont réellement coplanaires, aucun des deux ne se trouve réellement en face de l'autre et tout algorithme de tri en profondeur serait imprévisible.

Le tutoriel pour lequel vous avez posté un lien n'en parle que parce que le tri en profondeur est pertinent lorsque vous utilisez la transparence. Mais cela ne me semble pas être le but recherché.

Mais si vous devez vraiment le faire de cette façon, vous devez le faire vous-même. Envoyez d'abord votre carré blanc au pipeline de rendu, forcez le rendu, puis envoyez votre carré noir. Si vous le faites de cette façon et que vous désactivez la mise en mémoire tampon de la profondeur, les carrés peuvent être coplanaires et vous aurez toujours la garantie que le carré noir est tracé sur le carré blanc.

L'ordre des dessins est difficile. Il n'y a pas de solution facile. L'algorithme du peintre (trier les objets en fonction de leur distance par rapport à la vue de votre appareil photo) est le plus simple, mais comme vous l'avez découvert, il ne résout pas tous les cas.

Je suggérerais une combinaison de l’algroithme et des couches du peintre. Vous construisez des couches pour des éléments spécifiques de votre programme. Vous avez donc un calque d'arrière-plan, des calques d'objets, des calques à effets spéciaux et un calque d'interface graphique.

Utilisez l'algorithme du peintre sur les éléments de chaque couche. Dans certaines couches spéciales (comme votre couche d'interface graphique), ne triez pas avec l'algorithme du peintre, mais selon votre ordre d'appels. Vous appelez d'abord ce carré blanc pour qu'il soit tracé en premier.

Dessinez les éléments que vous souhaitez placer à l’arrière légèrement derrière ceux que vous souhaitez placer à l’avant. En d’autres termes, changez réellement la valeur z (en supposant que z est perpendiculaire au plan de l’écran). Il n'est pas nécessaire de le changer beaucoup pour que les objets soient dessinés les uns devant les autres. Et si vous ne modifiez que légèrement la valeur z, vous ne devriez pas remarquer de décalage important par rapport à la position souhaitée. Vous pouvez même aller vraiment très mal et calculer la position x, y correcte en fonction de la position z modifiée, de sorte que l'élément apparaisse à l'endroit où il est censé se trouver.

Vos documents seront dessinés dans l'ordre exact dans lequel vous appelez les fonctions glBegin / glEnd. Vous pouvez obtenir la mise en mémoire tampon en profondeur à l'aide du tampon z, et si vos objets 2D ont des valeurs z différentes, vous pouvez obtenir l'effet souhaité. de cette façon. Le comportement que vous décrivez sur le Mac est le seul moyen de voir si le programme dessine manuellement des éléments dans l'ordre inverse ou si vous utilisez le tampon z pour accomplir cela. Autrement, OpenGL n’a aucune fonctionnalité automatique comme vous le décrivez.

Comme AlanKley l’a souligné, la solution consiste à désactiver le tampon de profondeur. L'algorithme du peintre est en réalité une technique de conversion de balayage 2D utilisée pour restituer les polygones dans le bon ordre lorsque vous n'avez pas quelque chose comme un z-buffer. Mais vous ne l'appliqueriez pas aux polygones 3D. Vous devez généralement les transformer et les projeter (gérer les intersections avec d'autres polygones), puis trier la liste résultante des polygones projetés en 2D par leur coordonnée z projetée, puis les dessiner dans l'ordre z inversé.

J'ai toujours pensé à l'algorithme du peintre comme une autre technique d'élimination de la surface cachée lorsque vous ne pouvez pas (ou ne voulez pas) utiliser un tampon z.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top