2009-12-02 5 views
3

J'appelle actuellement Trace (méthode ci-dessous) à partir d'une boucle de jeu. À l'heure actuelle, tout ce que j'essaie de faire, c'est d'obtenir les coordonnées du monde à partir de la souris de l'écran pour pouvoir déplacer des objets dans l'espace du monde. Les valeurs que j'obtiens de gluUnProject sont cependant; me déroutant. J'utilisais glReadPixel (...) pour obtenir la valeur Z mais cela produisait peu ou pas de mouvement dans l'objet que je dessinais et le vecteur résultant finissait par être le même que l'emplacement de mes caméras (à l'exception de la minuscule décimale changements dus au mouvement de la souris), j'ai donc décidé de me débarrasser de l'appel et de remplacer la valeur Z par 1.Problèmes de coordonnées mondiales avec gluUnProject()

Ma question est la suivante: Le code suivant vous semble-t-il correct? Tous les exemples que j'ai pu voir sont soit identiques, soit très similaires, mais je n'arrive pas à produire des résultats corrects, même si je verrouille l'axe Y. Si le code est correct, alors je devine que je n'utilise pas correctement le vecteur résultant. Ne devrais-je pas être en mesure de dessiner un objet ou un point directement avec le vecteur résultant ou dois-je faire quelque chose d'autre avec lui, comme normaliser? Le mode de rendu actuel est GL_RENDER et j'utilise glFrustum avec une valeur NearZ de 1 et une valeur FarZ de 2048 pour créer une perspective. Il y a aussi une série de viewports créés avec des ciseaux, avec une taille et une largeur de 512x768 et positionnés dans chaque coin d'une fenêtre 1024x768. La trace (...) est appelée entre le rendu de la fenêtre supérieure gauche et est la seule projection perspective, tandis que les autres fenêtres sont orthographiques. FOV est mis à 45.

void VideoWindow::Trace(int cursorX, int cursorY) 
{ 
    double objX, objY, objZ;//holder for world coordinates 
    GLint view[4];//viewport dimensions+pos 
    GLdouble p[16];//projection matrix 
    GLdouble m[16];//modelview matrix 
    GLdouble z;//Z-Buffer Value? 

    glGetDoublev (GL_MODELVIEW_MATRIX, m); 
    glGetDoublev (GL_PROJECTION_MATRIX,p); 
    glGetIntegerv(GL_VIEWPORT, view); 

    //view[3]-cursorY = conversion from upper left (0,0) to lower left (0,0) 
    //Unproject 2D Screen coordinates into wonderful world coordinates 
    gluUnProject(cursorX, view[3]-cursorY, 1, m, p, view, &objX, &objY, &objZ); 

    //Do something useful here??? 
} 

Des idées? Editer: J'ai changé la valeur de winZ à 0.5 au lieu de 1 ce qui donne un vecteur plus raisonnable mais dessiner un point ne correspondait toujours pas à la souris. J'ai découvert que la valeur de view [3] était 384 ce qui est correct pour la fenêtre que j'utilise mais je l'ai remplacé par 768 (la taille réelle de la fenêtre) et le point a suivi la souris à 100%. Une autre expérimentation révèle que je ne peux pas utiliser les coordonnées pour se déplacer autour d'un objet 3D dans l'espace du monde en perspective en utilisant ces coordonnées, mais déplacer l'objet 3D dans l'espace orthographique fonctionne bien.

+0

Après avoir regardé le didacticiel NEHE sur gluUnProject, il m'a semblé que le didacticiel était identique à celui que j'avais, en utilisant glReadPixel.J'ai décidé de revenir sur mon code et d'utiliser glReadPixel et tout semble fonctionner correctement. –

Répondre

4

L'argument winz à gluUnproject spécifie la profondeur de la caméra à laquelle vous «choisissez» vos points. Comme vous l'avez indiqué, cette coordonnée devrait être dans la plage [0, 1].

Certains tutorials comme NeHes lire la coordonnée z du tampon de profondeur de sorte que vous "pick" à la bonne profondeur, bien sûr pour que cela fonctionne, vous devrez faire le projet gluUn après avoir tout rendu.

Peu importe, si vous définissez winz à 0,5 ou quelque chose (pas 0 ou 1 ou le point se termine sur le plan clip près ou de loin, et peut-être cueilli) et procédez comme suit:

gluUnProject(cursorX, view[3]-cursorY, 0.5, m, p, view, &objX, &objY, &objZ); 
//Do something useful here??? 
glPointSize(10); 
glBegin(GL_POINTS); 
glColor3f(1, 0, 0); 
glVertex3f(objX, objY, objZ); 
glEnd(); 

Vous devrait se retrouver avec un blob rouge sur le pointeur de la souris (à condition que rien d'autre ne l'écrase par la suite et que vous n'ayez pas d'états de rendu amusants qui rendent le point invisible).

+0

Initialement, les modifications que vous avez suggérées ne fonctionnaient pas mais après quelques expérimentations, j'ai trouvé que modifier la vue [3] (qui est 384, la taille de ma fenêtre) à 768 (taille de la fenêtre) le 0.5 a corrigé la position. Cependant, le mouvement de la souris semble seulement changer les coordonnées réelles par une fraction et le déplacement de la caméra elle-même est le seul moyen réel de modifier la position du vecteur plus d'une fraction. Par exemple, j'ai une grille sur laquelle je veux déplacer un objet, mais le vecteur de gluUnProject n'est pas si différent de la position de la caméra. –

0

juste une pensée, mais si le troisième argument à gluUnProject est la distance z à la caméra, ne importe quel point vous dessinez à cet endroit soit sur le plan de coupe près de votre tronc de cône? Mieux rendre cette valeur z un peu plus élevée.

+0

Si je me souviens bien, j'ai expérimenté des valeurs Z plus élevées allant de mon farZ (2048) à environ 10000. Il semblait que plus la valeur Z était élevée, moins les coordonnées de la souris avaient un effet sur le point 3D. Je pensais que la valeur Z était vraiment juste normalisée entre 0 (proche) et 1 (loin). –

Questions connexes