OpenGL can be picked up in two ways: first, Visual Object pickup 1. draw: a function is required to draw the same object in two modes; void renderobjects (gluint mode) {If (mode = gl_select ){
Glloadname (name); // set the name drawobj ();
} Else {drawobj ();}
}
2. Mouse processing:
Draw in select mode
Note: 1. correctly set and pick up the visual body, and restore the original visual body;
2. correct use of the original model view transformation; not necessarily need to be restored (if the model view does not change );
3. restore the original rendering status correctly. Pay attention to the underline;
Gluint selectbuff [512];
Glint hits, viewport [4];
Glselectbuffer (512, selectbuff );
Glgetintegerv (gl_viewport, viewport );
Glrendermode (gl_select); // enter the selection mode. The drawing will not be displayed;
Glinitnames ();
Glpushname (0 );
Int n = 3; // the floating range;
Glmatrixmode (gl_projection );
Glpushmatrix (); // Save the view matrix;
Glloadidentity (); // returns to zero for re-calculation;
Glupickmatrix (gldouble) x, (gldouble) (viewport [3]-y), N, N, viewport );
Gluperspective (60.0, (glsizei) 5/(glsizei) 5, 0.1, 10.0); // sets the loss of the visual body;
Gluortho2d (-0.6, 0.6, 0.6, 0.6 );
Glmatrixmode (gl_modelview );
Glpushmatrix ();
{
Gltranslatef (0, 0,-9.0f );
Gltranslatef (dx, Dy, Dz );
Glrotatef (angle, 0, 1.0f, 0 );
Gltranslatef (-96.0f,-94.0f,-56.0f );
} // Model view changes in the selection mode */
Renderobjects (gl_select); // draw in select mode; enter the drawing part
Glpopmatrix ();
Glmatrixmode (gl_projection );
Glpopmatrix ();
Glmatrixmode (gl_modelview );
Hits = glrendermode (gl_render );
Processhits (hits, selectbuff );
3. Processing: Pay attention to the structure of each collected data;
Number of names of the hit objects |
Depth value of the nearest vertex in this object |
Depth value of the nearest vertex in this object |
One of the names of the hit objects |
Name 2 of the hit object (If there are multiple names, and so on ...) |
Void processhits (glint hits, gluint buffer []) {/**/
Printf ("hits = % d \ n", hits );
Gluint * PTR = (gluint *) buffer;
Gluint names;
For (INT I = 0; I
Names = * PTR;
// Printf ("numeber of names for this hit = % d", names );
PTR ++;
// Printf ("\ t z1 is % F \ n", (float) * PTR/0x7fffffff );
PTR ++;
// Printf ("\ t z1 is % F \ n", (float) * PTR/0x7fffffff );
PTR ++;
// Printf ("\ tname are: % d \ n", * PTR );
Hited. push_back (* PTR );
PTR ++;
}
Glupostredisplay ();
}
4. Use of glupickmatrix;
5. obtain and use various matrices;
Second, Ray picking
Step 1:
ImplementationConverting screen coordinates to 3D World Space coordinates, Using functionsGluunprojectYou can directly obtain the three-dimensional coordinates corresponding to the screen coordinates.
[CPP]View plaincopy
- Gluunproject (gldouble) x POs, (gldouble) ypos, 1.0, mvmatrix, projmatrix, viewport, & wx, & Wy, & WZ );
- // Xpos, ypos is the screen coordinate of the origin in the lower left corner of the screen.
- // 1.0 indicates the world coordinate of zbuffer at 1.0 (the point of intersection of the distant shear plane ).
- // Mvmatrix is the view matrix, obtained through getdoublev( gl_modelview_matrix, mvmatrix)
- // Projmatrix is the projection matrix, which is obtained through glgetdoublev( gl_projection_matrix, projmatrix ).
- // The viewport is a viewport, which is obtained through glgetintegerv (gl_viewport, viewport ).
- // Wx, Wy, and WZ are the coordinates of the world we want to get. The two coordinates are determined by the rays.
- // Or you can use the origin point (viewpoint) to replace one of the points, because this Ray starts from the viewpoint.
Step 2:
UseIntersection of rays and triangles to be detectedThe principles and formulas used are as follows.
Principle 1: any point in a triangle can be determined by the U, V, and coordinates of the three vertices.
[CPP]View plaincopy
- Vpoint = V1 + u * (V2-V1) + V * (V3-V1 );
- // 0
- // V1, V2, and V3 are the three vertices of a triangle, which are known quantities.
Principle 2: any point on a Ray can be expressed by multiplying the direction vector (formatted) of the ray by its modulus (the vector length ).
[CPP]View plaincopy
- Vpoint = originpoint + dir * Len;
The intersection of rays and Triangles must satisfy the above two conditions at the same time, so there are:
[CPP]View plaincopy
- (-DIR) * Len + (V2-V1) * u + (V3-V1) * V = originPoint-V1;
Visualization entry 3: Pick up