Il picking in OpenGL si aggira tutto attorno al selection buffer che si ottiene tramite la funzione glSelectButter, ad esempio in questo modo:
#define MAX_BUFFER_SIZE 512
GLuint selectionBuffer[MAX_BUFFER_SIZE];
glSelectBuffer(MAX_BUFFER_SIZE, selectionBuffer);
Quando la rasterizzazione è in modalità selezione, allora OpenGL raccoglie informazini sulle primitive disegnate sulla vista, per ottenere la modalità selezione si usa:
glRenderMode(GL_SELECT);
Una volta che la modalità di rasterizzazione sarà commutata da GL_SELECT ad un'altra delle tre modalità possibili, il selection buffer avrà ricevuto le informazioni degli oggetti in vista.
GLint hits = glRenderMode(GL_RENDER);
// hits holds the number of diplayed objects.
Per vedere cosa c'é ora dentro al selection buffer si può fare così:
Questo codice controlla quanti oggetti sono "caduti" dentro il selecion buffer e seleziona tra tutti quello più vicino (i commenti li ho scritti tutti in inglese perché quando commento il codice scrivo in inglese). A questo punto sai quale oggetto è stato selezionato con il mouse e puoi cambiargli il colore.codice:#define MAXFLT 3.402823466e+38F // Maximum value for the float type. GLint nearest = -1; GLfloat zmin; GLfloat zmax; GLfloat min_depth = MAXFLT; GLuint * ptr = selectionBuffer for(i = 0 ; i < hits ; i++) { names = *ptr++; // Number of names in this hit. zmin = *ptr++; // Minimum depth of the current hit. zmax = *ptr++; // maximum depth of the current hit. // Now ptr points to the first name. for (j = 0; j < names; j++) // Loop through each name. { if(zmin < min_depth) // Selecting the nearest. { min_depth = zmin; nearest = *ptr; // Nearest object in the selection. } ptr++; // Go to the next name. } }
Per restringere la regione di selezione ad una piccola regione sotto il puntatore del mouse si usa gluPickMatrix. ad esempio:
GLint viewport[4];
glGetIntegerv( GL_VIEWPORT, viewport ); // Get viewport coordinates.
gluPickMatrix( x, (viewport[3] - y ), nPixel_x, nPixels_y, viewport );
I termini nPixel_x e nPixels_y corrispondono al numero di pixel che si vuole delimitino la regione di schermo da campionare, io di solito utilizzo 3x3 pixels o anche più.
Il nome è un identificativo numerico che va assegnato all'oggetto quando viene disegnato:
#define SPHERE 0
glPushName( SPHERE ); // Identify object to be drawn.
DrawSphere();
glPopName();
Ovviamente prima di adoperare i nomi in modalità selezione occorre inizializzare lo stack dei nomi di OpenGL con:
glInitNames();
Non è tutto, ma è un inizio.

Rispondi quotando