《基于MFC的OpenGL编程》Part 15 Selection
Selection
Selection is a powerful feature of OpenGL that allows you click at some position of the OpenGL window using the mouse and determine which of your objects lie beneath it. The act of selecting a specific object is called Picking. With OpenGL's selection feature, we can specify a viewing volume and determine which objects fall within that viewing volume. A powerful utility function, gluPickMatrix, produces a matrix which can be used to create a smaller viewing volume placed beneath the mouse cursor. Then we use selection to test this viewing volume to see which objects are contained by it.
Selection is actually a rendering mode, but in this mode no pisels are actually copied onto the frame buffer. Instead, primitives drawn within the viewing volume produce hit records in a selection buffer. We must set up this selection buffer in advance and name the primitives or groups of primitives so that they can be identified in the selection buffer.We can then parse the buffer to determine which objects intersected the viewing volume.
Naming Primitives
We have to name a group of primitives such as one describing a cube or a cylinder etc in order to identify them. These names are nothing but integers such as for display list names. The names list is maintained on the named stack. After we initialize the name stack we can push names on the stack or simply replace the name currently on the top of the stack. When a hit occurs during selection, all the names on the stack are copied onto the selection buffer.
1,在CCY457OpenGLView类中加入一个变量,用来表示宽高比
2,OnSize函数修改如下:
{
CView::OnSize(nType, cx, cy);
if ( 0 >= cx || 0 >= cy )
{
return;
}
// select the full client area
::glViewport(0, 0, cx, cy);
// compute the aspect ratio
// this will keep all dimension scales equal
m_aspectRatio = (GLdouble)cx/(GLdouble)cy;
// select the projection matrix and clear it
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
// select the viewing volume
::gluPerspective(45.0f, m_aspectRatio, .01f, 200.0f);
//::gluOrtho2D(-10.0f, 10.0f, -10.0f, 10.0f);
// switch back to the modelview matrix and clear it
::glMatrixMode(GL_MODELVIEW);
::glLoadIdentity();
}
3,绘制函数修改如下:
{//绘制函数
glTranslatef(0.0f,0.0f,-5.0f);
glRotatef(m_xRot,1.0f,0.0f,0.0f);
glRotatef(m_yRot,0.0f,1.0f,0.0f);
glInitNames();
glPushName(0);
glPushMatrix();
glTranslatef(-2.0f,0.0f,0.0f);
glLoadName(1);
glutSolidSphere(1.0f,20,20);
glPopMatrix();
glPushMatrix();
glLoadName(2);
glTranslatef(2.0f,0.0f,0.0f);
glutSolidCube(1.0f);
glPopMatrix();
}
4,加入对鼠标左键选择物体的处理
{
int xPos = point.x ;
int yPos = point.y ;
GLuint selectBuff[64];
GLint hits, viewport[4];
glSelectBuffer(64, selectBuff);
glGetIntegerv(GL_VIEWPORT, viewport);
glMatrixMode(GL_PROJECTION);
glPushMatrix();
glRenderMode(GL_SELECT);
glLoadIdentity();
gluPickMatrix(xPos, viewport[3] - yPos, 2,2, viewport);
gluPerspective(45.0f, m_aspectRatio, .01f, 200.0f);
RenderScene();
hits = glRenderMode(GL_RENDER);
if(hits==1)
ProcessObject(selectBuff);
glMatrixMode(GL_PROJECTION);
glPopMatrix();
glMatrixMode(GL_MODELVIEW);
}
void CCY457OpenGLView::ProcessObject (GLuint* pSelectBuff)
{
int id = pSelectBuff[3];
if(id==1)
MessageBox("You clicked on Sphere");
if(id==2)
MessageBox("You clicked on Cube");
}
void CCY457OpenGLView::OnLButtonDown(UINT nFlags, CPoint point)
{
ProcessSelection(point);
CView::OnLButtonDown(nFlags, point);
}
作者:洞庭散人
出处:http://phinecos.cnblogs.com/
posted on 2008-11-07 14:29 Phinecos(洞庭散人) 阅读(3466) 评论(1) 编辑 收藏 举报
【推荐】国内首个AI IDE,深度理解中文开发场景,立即下载体验Trae
【推荐】编程新体验,更懂你的AI,立即体验豆包MarsCode编程助手
【推荐】抖音旗下AI助手豆包,你的智能百科全书,全免费不限次数
【推荐】轻量又高性能的 SSH 工具 IShell:AI 加持,快人一步
· 如何编写易于单元测试的代码
· 10年+ .NET Coder 心语,封装的思维:从隐藏、稳定开始理解其本质意义
· .NET Core 中如何实现缓存的预热?
· 从 HTTP 原因短语缺失研究 HTTP/2 和 HTTP/3 的设计差异
· AI与.NET技术实操系列:向量存储与相似性搜索在 .NET 中的实现
· 周边上新:园子的第一款马克杯温暖上架
· Open-Sora 2.0 重磅开源!
· .NET周刊【3月第1期 2025-03-02】
· 分享 3 个 .NET 开源的文件压缩处理库,助力快速实现文件压缩解压功能!
· [AI/GPT/综述] AI Agent的设计模式综述