首页 > 代码库 > OpenGL拾取注意事项

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     else31     {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行           收集拾取信息

OpenGL拾取注意事项