Aller au contenu

[en investigation] [ C / OpenGL ]


Messages recommandés

Hello les inpactiens,

J'ai du mal a trouver la réponse a une question, et les exemples sur le net sont pas légions...

J'ai une scene opengl qui est un repere orthonormé x,y,z dans mon cas z ne m'interresse pas. J'ai mis au point le GL_Select pour que quand je clique je sache sur quel modele/Stack je clique et je sais sur quoi j'ai cliqué enfin bon bref ca ca marche .

Petit tracas, opengl comme dis plus haut travail en repere orthonormé dans mon cas a moi de -8 a 8, je me suis placé dans le coin 0 a 8 pour ma scene ce qui me simplifie mon probleme et ma permis de le resoudre _temporairement_ car c'est pas propre j'en suis sur.

Donc je voulais dire que quand une personne clique sur la scene, l'evenement me retourne une position x,y en pixel genre 89,112, bon ok sauf que moi en opengl je positionne les elements en coordonnées de 0 a 8 dans mon cas.

Ce que j'ai fait temporairement c'est de diviser ma taille ecran par le nombre de colonne ( 8 ) pour avoir la taille de la colonne, ensuite j'ai diviser l'endoir ou il a cliquer par la taille d'une colonne pour connaitre mon deplacement.

Le soucis dans cet hisrtoire c'est que le 8 je l'ai determiné au pif en deplacant un objet pour savoir ou etait la limite, donc j'aimerais savoir si il y avais une commande qui surement en fonction de la perspective et du viewport le retournerai la "grille" min, max visible ou un truc dugenre.

Donc en clair je voudrais convertir une coordonnées en pixel en coordonnées opengl X,Y ( ligne/colonnes)

Merci de vos lumieres sur le sujet :)

Lien vers le commentaire
Partager sur d’autres sites

Très bonne question !

J'ai bien bosser sur de l'openGL, mais plus sur un moteur utilsant OpenGL (openscenegraph). Donc a priori, je vois pas.

Je me prends une douche et je regarde si je peux aider :pleure:

EDIT : En fait ca me fait penser a un probleme que j'avais sur mon dernier projet a ma boite : Afficher un quad en fullscreen pour lui appliquer une texture modifiée par pixel shader. Du coup, fallait que le quad colle pile poil. Mais gt passé par une vue ortho, je ne sais pas si ca t'irait. Et puis bon, faut que je regarde le code d'openSceneGraph pour voir comment ct implémenté.

Mais ca veut dire que j'avais déjà lorgné sur un probleme similaire, je devrais pouvoir t'aider.

Lien vers le commentaire
Partager sur d’autres sites

Très bonne question !

J'ai bien bosser sur de l'openGL, mais plus sur un moteur utilsant OpenGL (openscenegraph). Donc a priori, je vois pas.

Je me prends une douche et je regarde si je peux aider :pleure:

Merci de me preter un peu ton cerveau :), je t'avoue hier soir ca a fait grand debat entre tuxxx,lorinc et moi meme sur le chan IRC pci.

Lorinc en etait meme arrivé a calcuer la surface de la projection grace au info de la camera, mais bon ca serait bien de voir la regle de l'art en la matiere :)

PS en terme de code pour l'instant, j'initialise la scene avec un glu perspective et je place ma camera avec glulookat.

Les 2 commandes sont des commandes GLU qui evite de faire 3-4 appel openGL ( notemment glfrustrum pour gluperspective) pour la vue .

Donc mon programme je les appelles come ca :

-Dans le configure event:

gluPerspective(60.0, 1.0, 0.0001, 1000.0);

-Dans le redraw de scene je place toujours ma camera:

gluLookAt ( cam_rotx, cam_roty, cam_rotz,

view_rotx, view_roty,view_rotz,

0, 1, 0);

Avec comme valeur par defaut pour la caméra:

view_rotx = 4.0, view_roty = -3.0, view_rotz =0.0 ;

cam_rotx = 4.0, cam_roty =-3.0, cam_rotz = 10.0;

Ce qui me donne a l'execution une grille de 0 a 8 en x-y. Comme dit plus haut , mon probleme et que le repere de 0 a 8 final, je l'ai obtenu en deplacant un objet pour savoir le min et max. Et les valeurs par defaut de la camera je les ai mises pour avoir une vue sur 0 a 8 au lieu de -8 a 8 si je la place par defaut a 0,0 au lieu de 4,0.

Lien vers le commentaire
Partager sur d’autres sites

Très bonne question !

J'ai bien bosser sur de l'openGL, mais plus sur un moteur utilsant OpenGL (openscenegraph). Donc a priori, je vois pas.

Je me prends une douche et je regarde si je peux aider :byebye:

Merci de me preter un peu ton cerveau :), je t'avoue hier soir ca a fait grand debat entre tuxxx,lorinc et moi meme sur le chan IRC pci.

Lorinc en etait meme arrivé a calcuer la surface de la projection grace au info de la camera, mais bon ca serait bien de voir la regle de l'art en la matiere :)

PS en terme de code pour l'instant, j'initialise la scene avec un glu perspective et je place ma camera avec glulookat.

Les 2 commandes sont des commandes GLU qui evite de faire 3-4 appel openGL ( notemment glfrustrum pour gluperspective) pour la vue .

Donc mon programme je les appelles come ca :

-Dans le configure event:

gluPerspective(60.0, 1.0, 0.0001, 1000.0);

-Dans le redraw de scene je place toujours ma camera:

gluLookAt ( cam_rotx, cam_roty, cam_rotz,

view_rotx, view_roty,view_rotz,

0, 1, 0);

Avec comme valeur par defaut pour la caméra:

view_rotx = 4.0, view_roty = -3.0, view_rotz =0.0 ;

cam_rotx = 4.0, cam_roty =-3.0, cam_rotz = 10.0;

Ce qui me donne a l'execution une grille de 0 a 8 en x-y. Comme dit plus haut , mon probleme et que le repere de 0 a 8 final, je l'ai obtenu en deplacant un objet pour savoir le min et max. Et les valeurs par defaut de la camera je les ai mises pour avoir une vue sur 0 a 8 au lieu de -8 a 8 si je la place par defaut a 0,0 au lieu de 4,0.

En fait j'ai pas le temps cet aprem, donc je verrai dans la semaine :phibee: Mais j'oublie pas. C'est juste que je suis extremement blindé

Lien vers le commentaire
Partager sur d’autres sites

quand tu fais le mouvement de cam arrière (pour simuler un zoom arrière), tu fais quoi exactement ?

je recule le Z de la camera, je pourrais toucher ou pas au point de vue. En tout cas une chose est sure si je recule la cam et que je touche pas au point de vue, le repere ortho change par exemple la je suis de 0 a 8 et si je la recule jaurai ptete 0,10.

Lien vers le commentaire
Partager sur d’autres sites

oui, mais tu sais de combien tu recules, non ?

dans ce cas, le calcul de surface que je t'ai donné hier devrais faire l'affaire.

quelque soit la position en Z de la cam, tan( fovy / 2) = Ymax / 2Z

donc ton Ymax = 2Z* tan( fovy / 2) avec le fovy en radian.

après, tu sais que Ymax / Xmax = 600 / 800, donc tu peux en déduire Xmax = 8/6 * Ymax

et la conversion depuis pixels est la suivante

sur X : X_ogl = X_pix * Xmax/800

sur Y : Y_ogl = Y_pix * Ymax/600

les deux seule inconues sont Z la profondeur de la cam (mais bon, tu devrais pouvoir la calculer à chaque mouvement) et le fovy. Or le fovy, tu l'as fixé au début : 60°

:craint:

Lien vers le commentaire
Partager sur d’autres sites

oui, mais tu sais de combien tu recules, non ?

dans ce cas, le calcul de surface que je t'ai donné hier devrais faire l'affaire.

quelque soit la position en Z de la cam, tan( fovy / 2) = Ymax / 2Z

donc ton Ymax = 2Z* tan( fovy / 2) avec le fovy en radian.

après, tu sais que Ymax / Xmax = 600 / 800, donc tu peux en déduire Xmax = 8/6 * Ymax

et la conversion depuis pixels est la suivante

sur X : X_ogl = X_pix * Xmax/800

sur Y : Y_ogl = Y_pix * Ymax/600

les deux seule inconues sont Z la profondeur de la cam (mais bon, tu devrais pouvoir la calculer à chaque mouvement) et le fovy. Or le fovy, tu l'as fixé au début : 60°

:p

Its working ! par contre aussi jai modifier ton algo pour avoir les coordonnées non inversées

Algo final:

#define DIG_2_RAD (G_PI / 180.0)

fYmax = (2*cam_rotz)* tan((60*DIG_2_RAD) / 2);

fXmax = 8/6 * fYmax;

fXView = event->x * (double)fXmax/(double)800;

fYView = event->y * -(double)fYmax/(double)600;

Bon reste juste la resolution et son ratio mais ca c'est bcps plus simple :)

Enfin avec un contexte en 800*600 et avec cet algo, je peux bouger ma camera sur le z et continuer a balayer toute ma surface avec mon objet lors du deplacement avec la souris.

:) Thks :oops:

Lien vers le commentaire
Partager sur d’autres sites

en fait il existe un fonction pour avoir la projection inverse : gluUnProject().

Exemple :

// x et y la pos du curseur
GLint viewport[4];
GLdouble mvmatrix[16], projmatrix[16];
GLdouble wx, wy, wz; // coordonnées x, y, z dans le repert ogl

glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev(GL_PROJECTIONMATRIX, projmatrix);

printf("les coord du curseurs sont %d - %d\n", x, y);

gluUnProject(x, y, 0.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

printf("les coord en z = 0.0 sont wx %f; wy %f; wz %f\n", wx, wy, wz);

Lien vers le commentaire
Partager sur d’autres sites

en fait il existe un fonction pour avoir la projection inverse : gluUnProject().

Exemple :

// x et y la pos du curseur
GLint viewport[4];
GLdouble mvmatrix[16], projmatrix[16];
GLdouble wx, wy, wz; // coordonnées x, y, z dans le repert ogl

glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev(GL_PROJECTIONMATRIX, projmatrix);

printf("les coord du curseurs sont %d - %d\n", x, y);

gluUnProject(x, y, 0.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);

printf("les coord en z = 0.0 sont wx %f; wy %f; wz %f\n", wx, wy, wz);

Ca doit pas marcher comme ca, car je l'ai implementé a la place de l'algo et ca marche pas, les valeurs retournés corresponde a pas grand chose.

Lien vers le commentaire
Partager sur d’autres sites

OpenGL prévoit deux modalités pour le picking selon le type d'information que l'on souhaite récupérer: le mode GL_SELECT, qui permet de savoir quel objet ou quelle face est visible, et le mode GL_FEEDBACK, qui permet d'obtenir toutes les informations disponibles sur la scène, coordonnées géométriques dans le repère écran, couleur, coordonnées textures (u,v), etc. On peut par exemple en tirer les coordonnées du point cliqué à la souris à la surface d'un objet. On active ce mode par glRenderMode(mode) (le mode de tracé normal avec affichage correspondant au mode GL_RENDER). Dans les deux cas il faut fournir un buffer où seront stockées les informations retournées par le geometric engine, avec selon le mode glSelectBuffer(size,buff) ou glFeedbackBuffer(size,GL_3D_COLOR_TEXTURE,buff).

On accède à ce buffer après être sorti du mode picking par

nbinfo = glRenderMode(GL_RENDER)

Je vais tenter ca pour voir :)

Lien vers le commentaire
Partager sur d’autres sites

  • 3 semaines après...

Désolé Tsu de ne pas avoir pu t'aider ce coup ci :dd:

Du coup je vais lire comment s'est reglé le probleme :)

Ba il y a un truc que j'ai pas compris, enfin j'ai gardé la methode calcule de projection. Normalement la commande GLUnProject sert a ca mais moi elle me retourne n'importe quoi. Donc a mon avis pour ce servir de GLUnproject il faut initialiser sa vue et sa scene avec gluproject.

Mais comme les commandes GLU c'est des commandes RAD, il serait interressant de savoir ce qui ce cache comme commande opengl derriere, si ca ce trouve on retomberai sur un calcul de projection.

Lien vers le commentaire
Partager sur d’autres sites

Désolé Tsu de ne pas avoir pu t'aider ce coup ci :corde:

Du coup je vais lire comment s'est reglé le probleme :)

Ba il y a un truc que j'ai pas compris, enfin j'ai gardé la methode calcule de projection. Normalement la commande GLUnProject sert a ca mais moi elle me retourne n'importe quoi. Donc a mon avis pour ce servir de GLUnproject il faut initialiser sa vue et sa scene avec gluproject.

Mais comme les commandes GLU c'est des commandes RAD, il serait interressant de savoir ce qui ce cache comme commande opengl derriere, si ca ce trouve on retomberai sur un calcul de projection.

reste plus qu'a regarder dans le source :up: (je sais plus quelle librairie c'est par contre, j'imagine libglu :love:, mais pour glut, c'est sous freeglut généralement...)

Lien vers le commentaire
Partager sur d’autres sites

Archivé

Ce sujet est désormais archivé et ne peut plus recevoir de nouvelles réponses.

×
×
  • Créer...