OpenGL拾取注意事项

GLFrame框架本身不支持拾取,需要自己实现.以下代码是实现拾取功能的注意事项:

 1 void Test::doSelection(int xPos, int yPos)
 2 {
 3     GLfloat aspect;
 4     GLint    hits, viewport[4];//x,y,width,height
 5     glSelectBuffer(BUFFER_LENGTH, pickBuffer);    //设置选择缓冲区
 6     glGetIntegerv(GL_VIEWPORT, viewport);        //获取可视区域
 7     glMatrixMode(GL_PROJECTION);                //切换矩阵模式为投影模式并保存当前矩阵
 8     glPushMatrix();
 9     glRenderMode(GL_SELECT);                    //改变渲染模式为选择模式
10     glLoadIdentity();        //以 xPos、yPos 为中心建立新的单位立方体裁剪区,并向外扩展两个像素
11     int yPosNew= viewport[3] - yPos + viewport[1];
12     gluPickMatrix(xPos, yPosNew ,    1.0f,    1.0f,    viewport);
13     aspect = GLfloat(viewport[2]) / GLfloat(viewport[3]);
14     gluPerspective(45.0f, aspect, 0.1f, 300.0f);//很重要的设置
15     Draw();                                        //绘制场景
16     hits = glRenderMode(GL_RENDER);                //收集单击记录
17     glMatrixMode(GL_PROJECTION);
18     glPopMatrix();
19     glMatrixMode(GL_MODELVIEW);                    //恢复矩阵模式为模型视图模式
20     if(hits >= 1)
21     {
22         char str[255];
23         memset(str,'\0',255);
24         for(int i=0;i<20;i+=4)
25         {
26             sprintf(str,"选中物体的个数:%d  最小深度:%f 最大深度:%f 物体名字:%d\n",pickBuffer[i],(float)pickBuffer[i+1]/(float)0xffffffff,(float)pickBuffer[i+2]/(float)0xffffffff,pickBuffer[i+3]);
27             MessageBox(NULL,str,"提示",MB_OK);
28         }
29     }
30     else
31     {
32         char str[255];
33         memset(str,'\0',255);
34         sprintf(str,"%s","你击中了空白!");
35         MessageBox(NULL,str,"提示",MB_OK);
36     }
37 }

1行             xPos,yPos是相对坐标,而非绝对坐标

9行             切换为选择模式

13行~14行  必须加,对GLFrame没有影响,因为7~8两行代码

15行           Draw函数(针对拾取,还要在draw中的glLoadIdentity();后再加上glInitNames();glPushName(0);两行代码)
16行           收集拾取信息

posted @ 2014-12-01 22:15  一名老程序员  阅读(267)  评论(0编辑  收藏  举报