《基于MFC的OpenGL编程》Part 14 Selection
来源:互联网 发布:怎么在淘宝搜岛国片 编辑:程序博客网 时间:2024/05/22 03:50
《基于MFC的OpenGL编程》Part 14 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、在CMy2OpenGLView类中加入一个变量,用来表示宽高比:
GLdouble m_aspectRatio;//width/height ratio
2、OnSize函数修改如下,主要将aspect_ratio换成了成员变量m_aspectRatio:
void CMy2OpenGLView::OnSize(UINT nType, int cx, int cy) {CView::OnSize(nType, cx, cy);// TODO: Add your message handler code here//GLdouble aspect_ratio; // width/height ratio 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//gluOrtho2D(60.0,100.0*aspect_ratio,0.0,100.0); //gluOrtho2D(-10.0,10.0,-10.0,10.0);//画三个点时,一点要设置成这样,不然编译出来显示不了图形//主要是这个函数,注意参数设置,不然看不到效果的 gluPerspective(30.0f, m_aspectRatio, 3.0f, 10.0f); // switch back to the modelview matrix and clear it ::glMatrixMode(GL_MODELVIEW); ::glLoadIdentity();//::glDrawBuffer(GL_BACK);}
3、绘制函数如下:
注意:函数中注释的代码不加也可以选中对象,但是查资料看到大多数都有加上,建议加上
void CMy2OpenGLView::RenderSceneSelect(){//绘制函数//glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);// glMatrixMode(GL_MODELVIEW);// glLoadIdentity();// glPushMatrix(); 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);//push一次才有栈顶,才能有后面的glLoadName()//绘制球体 glPushMatrix(); glColor3f(0.0f,0.0f,1.0f); glTranslatef(-2.0f,0.0f,0.0f); glLoadName(1); glutSolidSphere(1.0f,20,20); glPopMatrix();//绘制立方体 glPushMatrix(); glColor3f(0.5f,0.0f,0.5f); glLoadName(2); glTranslatef(2.0f,0.0f,0.0f); glutSolidCube(1.0f); glPopMatrix();glPopMatrix();}
4、加入对鼠标左键选择物体的处理:
注意:RenderSceneSelect()是我们的画图函数,改了名字后一定要和自己的文件名字一致,否则不会出现选中后弹出 MessageBox的消息框。
void CMy2OpenGLView::ProcessSelection(CPoint point){ 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()为RenderSceneSelect()名字的一定要注意了, //很可能就是这句导致你选择物体后没反应 ///////******************************************///////// RenderSceneSelect(); ///////******************************************///////// hits = glRenderMode(GL_RENDER); if(hits==1) ProcessObject(selectBuff); glMatrixMode(GL_PROJECTION); glPopMatrix(); glMatrixMode(GL_MODELVIEW);}void CMy2OpenGLView::ProcessObject(GLuint *pSelectBuff){ int id = pSelectBuff[3]; if(id==1) MessageBox("You clicked on Sphere"); if(id==2) MessageBox("You clicked on Cube");}void CMy2OpenGLView::OnRButtonDown(UINT nFlags, CPoint point) {// TODO: Add your message handler code here and/or call defaultProcessSelection(point);CView::OnRButtonDown(nFlags, point);}
5、修改OnDraw()函数,为了效果更好,我把RenderScene()和RenderScene3D()注释掉了,加上RenderSceneSelect()函数:
void CMy2OpenGLView::OnDraw(CDC* pDC){CMy2OpenGLDoc* pDoc = GetDocument();ASSERT_VALID(pDoc);// TODO: add draw code for native data herem_ElapsedTime = ::timeGetTime(); // get current time if(ElapsedTimeinMSSinceLastRender()<30)return ; // Clear out the color & depth buffers ::glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );::glClearColor(0.0,0.0,0.5,0.5);//此函数在InitialOpenGL函数中设置默认的背景,此处重新设置,为蓝色背景glPushMatrix();//RenderScene(); //RenderScene3D();RenderSceneSelect();glPopMatrix(); glFlush(); // Tell OpenGL to flush its pipeline ::glFinish(); // Now Swap the buffers ::SwapBuffers( m_pDC->GetSafeHdc() ); //SwapBuffers(pDC->m_hDC);//Perform Post Display Processing//Only update the title every 15 redraws (this is about every 1/2 second)PostRenderScene();//此函数可以让标题显示出帧速率,没必要在OnCreate()额外加那两行//the very last thing we do is save//the elapsed time,this is use with the//next elapsed time to calculate the elapsed time since a render and the frame ratem_previousElapsedTime=m_ElapsedTime;}
- 《基于MFC的OpenGL编程》Part 14 Selection
- 《基于MFC的OpenGL编程》Part 15 Selection
- 《基于MFC的OpenGL编程》Part 14 Quadrics
- 《基于MFC的OpenGL编程》Part 17 Shadows
- 《基于MFC的OpenGL编程》Part 16 Reflection
- 《基于MFC的OpenGL编程》Part 10 Texture Mapping
- 《基于MFC的OpenGL编程》Part 9 Lighting
- 《基于MFC的OpenGL编程》Part 8 Colors
- 《基于MFC的OpenGL编程》Part 7 Animation
- 《基于MFC的OpenGL编程》Part 1 A Primer
- 《基于MFC的OpenGL编程》Part 1 A Primer
- 《基于MFC的OpenGL编程》Part 6 Animation
- 《基于MFC的OpenGL编程》Part 7 Colors
- 《基于MFC的OpenGL编程》Part 8 Lighting
- 《基于MFC的OpenGL编程》Part 9 Texture Mapping
- 《基于MFC的OpenGL编程》Part 13 Quadrics
- 《基于MFC的OpenGL编程》Part 15 Reflection
- 《基于MFC的OpenGL编程》Part 0 基于MFC的OpenGL基本框架
- 如何处理监控类直播中遇到的奇葩问题
- Mycat性能测试
- Spring 实践 -AOP
- (转)翻页功能的实现
- Could not create the view: An unexpected exception was thrown.问题解决
- 《基于MFC的OpenGL编程》Part 14 Selection
- Netty4.0学习笔记系列之二:Handler的执行顺序
- 20160307 Windows下mingw32-make找不到QApplication的解决办法
- [从头学数学] 第124节 不等式与不等式组
- Java堆内存
- Java .作业1
- android studio 报Android NDK: Aborting... . Stop.
- Delphi常用日期函数
- HTML DOM Anchor 对象