2009-06-23 6 views
2

En OpenGL dans Delphi, j'essaie de calculer combien de scène est visible en trouvant les étendues gauche, droite, supérieure et inférieure de la zone de visualisation dans un projection orthographique. Cela rendra certaines interactions de la souris semblent être 1-à-1. Je n'ai pas beaucoup accès au code qui met en place la matrice de projection orthographique, mais je sais qu'il appelle glOrtho (...) pour mettre en place la matrice de projection. Je dois être capable de prendre un avion cartésien (pas un plan polygonal rendu), puis calculer les bords gauche, droit, supérieur et inférieur du tronc de visionnage à partir de toute l'information que l'opengl peut fournir (je me fiche de les plans de coupe avant et arrière). Je n'ai pas accès au code qui définit le volume de visualisation (en utilisant GLScene pour Delphi), de sorte que la seule information que je puisse utiliser pour trouver ces informations (pour autant que je sache) estJe dois calculer les bords de l'espace visible à partir de l'état OpenGL actuel

glGet(GL_PROJECTION_MATRIX, @projectionMatrix); 

Based sur la documentation en http://www.talisman.org/opengl-1.1/Reference/glOrtho.html, j'ai décidé que je pouvais faire quelques calculs pour calculer ce que les extensions gauche, droite, haut et bas étaient pour le plan proche (ce qui en mode ortho est suffisant) (voir mon code ci-dessous). Cependant, quand je regarde réellement les valeurs que je récupère de glGet, je vois une matrice avec des valeurs qui ne correspondent pas à la description dans le lien de documentation que j'ai donné plus haut (voir les données de matrice ci-dessous). Avec de tels nombres décevants, j'ai des doutes quant à savoir si j'utilise glGet correctement, et si je peux réellement compter sur ces nombres pour me donner les étendues gauche/droite/haut/bas du volume visible. Je suppose que je pourrais aussi faire une erreur en Delphi, mais je ne sais pas ce que ce serait.

Dans ce cas particulier, le plan est orienté pour faire directement face à la caméra et la caméra a une projection orthogonale. Je ne suis pas un contrôle complet de la façon dont la matrice de projection est mis en place, donc je l'avais espéré que je pourrais calculer le bord gauche comme

left = 2/(A * (tx - 1)/(tx+1) - 1) 

A et tx sont récupérés à partir de la matrice de projection, comme indiqué à http://www.talisman.org/opengl-1.1/Reference/glOrtho.html (I Je ne montre pas comment j'ai dérivé la formule ci-dessus, donc il pourrait être incorrect - en ce moment, il donne une réponse de -INF). Le code que j'utilisais pour récupérer les valeurs de la matrice de projection est la suivante:

var 
    projectionMatrix: TMatrix; 
    Left, Right, Top, Bottom: Single; 
    A, B, C, tx, ty, tz: Single; 
begin 
    A := projectionMatrix[0][0]; 
    B := projectionMatrix[1][1]; 
    C := projectionMatrix[2][2]; 
    tx := projectionMatrix[0][3]; 
    ty := projectionMatrix[1][3]; 
    tz := projectionMatrix[2][3]; 

    Left := 2/(A * ((tx - 1)/(tx + 1) - 1)); 
    ShowMessage(FloatToStr(A)); 
    //etc... 

Les valeurs de la matrice que je vois sont à peu près comme ceci:

[0] (0, 1.7436188636e-39, 6.4310754487e+37, 1.3822464104e-39) 
[1] (3.8535707769e-43, 1.4012984643e-45, 0, 2.8086960027e+32) 
[2] (-4.20345941e+17, 0, 1.7437029415e-39, 2.8086960027e+32) 
[3] (1.7437645986e-39, 6.4311900443e+37, +NAN, 1.7437645986e-39) 

[Modifier] GLScene a les déclarations suivantes:

TMatrix = THomogeneousFltMatrix; 
THomogeneousFltMatrix = TMatrix4f; 
TMatrix4f = array[0..3] of TVector4f; 
TVector4f = array[0..3] of single; 

[Modifier] Si je change la matrice de projection à un tableau de 16 valeur, voici ce qui se passe:Le tableau résultant est constitué des éléments 0 à 16, ce qui ne semble toujours pas correct.

ProjectionMatrix (5.9208279286e-39, -1536643072, 1,2429653406, -1.2128044229e-11, 2,8763115406, 0, 4,728515625, 1.7430022923e-39, 6.5138089186e + 37, + 30 -3.7955583126e, -2,4000201225, -3.7955583126e + 30, 2,4000201225, -1.2128044229e-11, 2,6263115406, -1.2128044229e-11, -2,6263115406) ​​

+1

Pouvez-vous montrer la déclaration de TMatrix? Pouvez-vous afficher le code exact de votre appel à glGet()? –

+1

comme l'a déjà dit Alistar, vérifiez votre déclaration TMatrix. Essentiellement, il doit être 16 flotteurs de précision simple consécutifs en mémoire, pas 4 pointeurs à 4 flotteurs. – heeen

+0

Elles proviennent toutes de la bibliothèque glScene: TMatrix = THomogeneousFltMatrix; THomogeneousFltMatrix = TMatrix4f; TMatrix4f = tableau [0..3] de TVector4f; TVector4f = array [0..3] de single; Il semble que Heeen soit sur la bonne voie. –

Répondre

1

Vous semblez utiliser GLScene. Pourquoi ne pas utiliser TGLSceneBuffer.ScreenVectorIntersectWithPlane()?

Vous obtenez 4 vecteurs mondiaux parmi les 4 coordonnées d'écran et vous disposez d'un rectangle dont vous pouvez facilement calculer la surface.

+0

Je n'ai jamais eu l'occasion de l'utiliser, mais je pense que c'est la bonne solution - et je ne veux pas laisser ce "sans réponse" pour d'autres raisons. –

Questions connexes