web-dev-qa-db-fra.com

Comment transformer le monde 2D en coordonnées d'écran OpenGL

Je travaille actuellement sur l'implémentation d'un moteur de rendu OpenGL dans un moteur de jeu 2D.

Parce que l'espace de coordonnées d'écran OpenGL est [-1,1], je suis un peu confus quant à la façon dont il doit être interfacé avec un système de coordonnées universelles cartésiennes 2D.

Disons que la fenêtre d'affichage dans mon monde est de [-500, -500] à [1200, 1200], où [0, 0] est l'origine du monde. Dois-je seulement traduire et réduire les coordonnées entre -1 et 1? Ou existe-t-il une autre forme de transformation qui doit être effectuée?

Comment calculer où dessiner à l'écran des objets qui ont des positions définies dans votre propre système de coordonnées?

J'apprécierais une explication avec et sans glOrtho (afin que nous puissions également utiliser l'axe Z pour les effets de perspective).

21
bgroenks

Tout d'abord, OpenGL utilise plusieurs systèmes de coordonnées, il n'y a donc pas " le système de coordonnées OpenGL". Vous faites référence à des coordonnées de périphérique normalisées (NDC), où les trois coordonnées sont dans la plage [-1, 1]. Les différents systèmes de coordonnées et leurs noms sont expliqués ici , dans la section "9.011 Comment les coordonnées sont-elles transformées? Quels sont les différents espaces de coordonnées?". 1)

Deuxièmement, pour éviter toute confusion, dans OpenGL, le terme "fenêtre" fait référence à la partie de la fenêtre dans laquelle vous effectuez le rendu, et elle est en coordonnées de fenêtre. Dans votre question, vous l'avez utilisé pour décrire la partie (l, r, t, b) = (- 500, -500, 1200, 1200) de votre monde que vous souhaitez rendre, qui est en coordonnées universelles.

Vous avez demandé comment "calculer où dessiner des objets à l'écran". Ce que vous devez faire est de définir une transformation (une matrice 4x4) qui mappe d'un système de coordonnées à un autre. Votre monde 2D est donné en coordonnées mondiales, vous devez donc définir une matrice qui transforme les coordonnées mondiales en NDC, c'est-à-dire une matrice de projection. Dans vos shaders, vous multipliez simplement vos sommets avec cette matrice de projection et vous obtenez des NDC. glm::ortho/glOrtho calcule une telle matrice de projection. Quant à la projection en perspective, ce que vous voulez faire n'est pas clair, mais vous devriez expérimenter avec les fonctions perspective et lookat dans glm.

Pour être clair, vous définissez les sommets dans le système de coordonnées de votre choix (qui est appelé le système de coordonnées mondial) et dessinez simplement ces sommets. Le travail de votre vertex shader consiste à appliquer la transformation que vous avez définie.

Notez également que vous avez spécifié un carré et que ce n'est généralement pas ce que vous voulez. Les moniteurs et la plupart des fenêtres ne sont pas carrés, donc si vous mappez ce carré sur une fenêtre typique, vous obtiendrez une vue déformée de votre monde. Vous devez prendre en compte le rapport hauteur/largeur (largeur: hauteur) de la fenêtre. J'ai essayé d'expliquer cela ici .


1) En guise de remarque, le FAQ est assez ancien et fait référence aux anciennes versions d'OpenGL. De nos jours, les programmeurs sont censés et encouragés à gérer à la fois la vue du modèle et les matrices de projection elles-mêmes, puisque vous en avez besoin dans vos shaders. Je recommande fortement glm , il est uniquement en-tête donc très facile à intégrer, et a une syntaxe sympa qui reflète GLSL.

19

Utilisez glOrtho sur la matrice de projection, puis dessinez normalement. Pour votre exemple, je suppose que vous voulez glOrtho (0, 1000, 0, 3000, -1, 1) qui vous donnerait une fenêtre de 1000 unités de largeur et 3000 unités de hauteur

2
Tim Mutton

Placez votre scène dans le système de coordonnées de votre choix. Je recommande d'utiliser glm ( http://glm.g-truc.net/ ) pour initialiser les matrices et effectuer des opérations mathématiques, etc. Vous avez donc probablement un moteur de graphe de scène, où vous gérez tous les objets dans votre monde 2D/3D. Il suffit de configurer la vue et la projection correctement dans glm. En fait, vous ne devriez pas avoir besoin de détails d'implémentation de pipeline graphique - il pourrait donc y avoir une mauvaise décision de conception dans votre moteur de jeu.

0
dinony