J'utilise SDL avec OpenGL et jusqu'à maintenant, je l'ai fait tout en 2D (avec glOrtho())En utilisant gluUnProject() pour dessiner un quad à la position du curseur
Maintenant, je veux essayer de dessiner les choses en 3D mais bien sûr, puisque j'ai maintenant jeté une troisième dimension dans le mélange, les choses deviennent plus compliquées. Ce que je veux faire est de prendre les coordonnées du curseur à l'écran, de les traduire en (?) Coordonnées du monde (coordonnées que je peux utiliser dans OpenGL puisque j'ai maintenant la perspective etc.), et dessiner un quad à cette position (le curseur de la souris étant au centre du quad)
J'ai lu quelques tutoriels sur gluUnProject() et je comprends en quelque sorte ce que je suis censé faire, mais puisque j'apprends par moi-même, il est très facile d'être confus et de ne pas bien comprendre ce que je fais. En tant que tel, j'ai principalement copié à partir d'exemples que j'ai trouvés.
Ci-dessous mon code (j'ai pris le contrôle d'erreur, etc. pour tenter de le couper un peu) Comme vous pouvez le voir
, j'ai des variables mouseX, mouseY et mouseZ, dont mouseX et mouseY obtiennent leur valeurs de SDL.
J'ai essayé d'utiliser glReadPixel() pour obtenir mouseZ mais je ne suis pas sûr de le faire correctement. Le problème est que quand je clique, le quad n'est pas dessiné dans la position correcte (je suppose en partie du fait que je ne sais pas comment obtenir mouseZ correctement, donc je l'ai juste remplacé dans gluUnProject() avec 1.0?)
J'utilise les nouvelles coordonnées (wx, wy, wz) dans la fonction glTranslatef() mais encore une fois parce que je ne sais pas comment obtenir mouseZ correctement, je suppose que c'est la raison ça ne fonctionne pas correctement. Si je remplace wz avec -499 cela semble fonctionner, mais je dois savoir comment obtenir des résultats précis sans trouver manuellement les numéros corrects (ou presque)
Si quelqu'un peut me dire ce que je fais mal, ou donnez-moi des conseils ce serait grandement apprécié.
#include <SDL/SDL.h>
#include <SDL/SDL_opengl.h>
SDL_Surface* screen = 0;
SDL_Event event;
bool isRunning = true;
int mouseX, mouseY, mouseZ = 0;
GLint viewport[4];
GLdouble mvmatrix[16], projmatrix[16];
GLint realY; /* OpenGL y coordinate position */
GLdouble wx, wy, wz; /* returned world x, y, z coords */
int main(int argc, char **argv) {
SDL_Init(SDL_INIT_EVERYTHING);
screen = SDL_SetVideoMode(800, 600, 32, SDL_OPENGL);
glEnable(GL_DEPTH_TEST);
glDepthMask(GL_TRUE);
glViewport(0, 0, 800, 600);
glClearDepth(1.f);
glClearColor(0, 0, 0, 0);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(90.f, 1.f, 1.f, 500.f);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
while(isRunning) {
while(SDL_PollEvent(&event)) {
if(event.type == SDL_QUIT) {
isRunning = false;
}
if(event.type == SDL_MOUSEBUTTONDOWN) {
if(event.button.button == SDL_BUTTON_LEFT) {
SDL_GetMouseState(&mouseX, &mouseY);
glGetIntegerv(GL_VIEWPORT, viewport);
glGetDoublev(GL_MODELVIEW_MATRIX, mvmatrix);
glGetDoublev(GL_PROJECTION_MATRIX, projmatrix);
realY = viewport[3] - (GLint) mouseY - 1;
glReadPixels(mouseX, realY, 1, 1, GL_DEPTH_COMPONENT, GL_FLOAT, &mouseZ);
gluUnProject((GLdouble)mouseX, (GLdouble)realY, 1.0, mvmatrix, projmatrix, viewport, &wx, &wy, &wz);
}
}
}
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glPushMatrix();
glTranslatef(wx, wy, wz);
glBegin(GL_QUADS);
glColor4f(1.f, 0.f, 0.f, 1.f);
glVertex3f(-20.f, -20.f, 0.f);
glColor4f(0.f, 1.f, 0.f, 1.f);
glVertex3f(-20.f, 20.f, 0.f);
glColor4f(0.f, 0.f, 1.f, 1.f);
glVertex3f(20.f, 20.f, 0.f);
glColor4f(1.f, 0.f, 1.f, 1.f);
glVertex3f(20.f, -20.f, 0.f);
glEnd();
glPopMatrix();
SDL_GL_SwapBuffers();
}
SDL_FreeSurface(screen);
return 0;
}
Donc, juste pour vérifier ma compréhension, si je voulais trouver la valeur Z correcte, j'aurais d'abord besoin d'une surface sur laquelle je veux placer le quad? –
pour la première option oui si vous voulez que ce quad vive dans l'espace 3D. Si vous n'avez aucun objet tel qu'il semble, vous pouvez utiliser un plan de projection orthogonal à la direction de la caméra. C'est ce que vous faites en utilisant un Z fixe comme vous l'avez dit. Mais vous devez trouver le bon Z pour faire correspondre les coordonnées des pixels. Cela dépend de votre matrice de projection. Donc, je pense qu'il est plus facile de simplement passer la matrice de projection en 2D pour dessiner votre quad. –