zoukankan      html  css  js  c++  java
  • 【转】 《基于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类中加入一个变量,用来表示宽高比

           GLdouble m_aspectRatio; // width/height ratio

    2OnSize函数修改如下:

    void CCY457OpenGLView::OnSize(UINT nType, int cx, int cy)
    {
           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,绘制函数修改如下:

    void CCY457OpenGLView::RenderScene ()
    {
    //绘制函数

           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,加入对鼠标左键选择物体的处理

    void CCY457OpenGLView::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();
           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);
    }

  • 相关阅读:
    北斗对时设备(GPS校时产品)在数字城市系统中的应用
    京准电子,北斗授时产品取代GPS对时设备服务各行业
    北斗校时系统(GPS授时设备)几种时间同步方法
    网络对时服务器(NTP校时服务器)应用港口信息化系统
    关于医院NTP授时服务器(NTP校时服务器)部署工作
    变电站里NTP校时器(gps网络时间服务器)产品的应用
    C++学习(二十九)(C语言部分)之 顺序表
    C++学习(二十八)(C语言部分)之 文件操作
    C++学习(二十七)(C语言部分)之 预处理命令
    C++学习(二十六)(C语言部分)之 结构体3(联合,枚举)
  • 原文地址:https://www.cnblogs.com/lcxu2/p/2004055.html
Copyright © 2011-2022 走看看