65.9K
CodeProject 正在变化。 阅读更多。
Home

如何使用 OpenGL 选择对象

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.61/5 (17投票s)

2003年10月30日

CPOL

1分钟阅读

viewsIcon

165221

downloadIcon

8968

本文档解释了如何使用 OpenGL 选择对象。

Sample Image

引言

我来自越南,英语不太好。但我希望您能理解我的文章。我尝试编写一个游戏作为我的学校项目。我决定使用 3D 技术编写它,并为此使用了 OpenGL。我一直在寻找一种在 3D 中选择大量对象的方法,并且找到了它。 在本文中,我想向您介绍如何操作。

使用代码

在这个例子中,我使用 MFC 向导。 我的所有代码都写在 CView 上。

添加变量

private:
    GLdouble gldAspect;
    GLsizei glnWidth, glnHeight;
    HGLRC hRC;
    Cube cube[4];
    double r;

CubeMyOpenGL.h 中定义。

使用“类向导”进行消息映射:WM_CREATEWM_DESTROYWM_EARSEBKGNDWM_LBUTTONDOWNWM_PAINTWM_SIZEWM_TIMER

在 CodeProject 上关于 OpenGL 的另一篇文章中,你可以看到 WM_SIZEWM_PAINTWM_CREATE 的代码(我再次使用了代码! 感谢作者的代码!)。

此外,在 WM_CREATE 中,初始化一些变量并启动动画计时器。

int CTry_OpenGLView::OnCreate(LPCREATESTRUCT lpCreateStruct) 
{
     if (CView::OnCreate(lpCreateStruct) == -1)
          return -1;
     
     // TODO: Add your specialized creation code here
     hRC=SetUpOpenGL(m_hWnd);
     for(int i=0;i<4;i++) cube[i].x=i*2-3;
     r=0;
     SetTimer(1000,100,NULL);

     return 0;
}

当然,在 OnDestroy() 中停止计时器。

定时器

void CTry_OpenGLView::OnTimer(UINT nIDEvent) 
{
     r+=5;
     if(r>=360) r=0;
     RedrawWindow();

     CView::OnTimer(nIDEvent);
}

OnEraseBkgnd 中:删除所有内容(否则屏幕会“闪烁”)。

现在,选择对象的代码

void CTry_OpenGLView::OnLButtonDown(UINT nFlags, CPoint point) 
{
     // TODO: Add your message handler code here and/or call default
    GLuint selectBuf[BUFSIZE];
    GLint hits;
    GLint viewport[4];

     HDC hDC = ::GetDC(this->m_hWnd);
     wglMakeCurrent(hDC,hRC);

    glGetIntegerv (GL_VIEWPORT, viewport);
    glSelectBuffer (BUFSIZE, selectBuf);

    glRenderMode(GL_SELECT); // Enter the SELECT render mode
    glInitNames();
    glPushName(-1);

    glMatrixMode (GL_PROJECTION);
    glPushMatrix ();
    glLoadIdentity ();
    gluPickMatrix((GLdouble) point.x, 
          (GLdouble) (viewport[3] - point.y), 
          5.0, 5.0, viewport);
    gluPerspective(30.0,gldAspect,1.0,20.0);
    glMatrixMode(GL_MODELVIEW);
    PaintScreen(GL_SELECT);//function paint the objects.
    glPopMatrix ();
    glFlush ();

    hits = glRenderMode (GL_RENDER);

     glMatrixMode(GL_PROJECTION);
     glLoadIdentity();
     glViewport(0,0,glnWidth,glnHeight);
     gluPerspective(30.0,gldAspect,1.0,20.0);
    
     /*for(int i=0;i<hits;i++)
     {
          cube[selectBuf[3+i*4]].selected= 
             !cube[selectBuf[3+i*4]].selected;
     }//select all (include the hide object)!
     */
     if (hits)
     {
          int n=0;double minz=selectBuf[1];
          for(int i=1;i<hits;i++)
          {
               if (selectBuf[1+i*4]<minz) 
                 {n=i;minz=selectBuf[1+i*4];}
          }
          cube[selectBuf[3+n*4]].selected=
              !cube[selectBuf[3+n*4]].selected;
     }//only select the object we see (nearest object)!

     wglMakeCurrent( NULL, NULL );
    ::ReleaseDC( this->m_hWnd, hDC );

     CView::OnLButtonDown(nFlags, point);
}

关注点

很简单,不是吗? 我的源代码有一些冗余,我想。 如果您能帮助我删除它,非常感谢! ^_^

历史

  • 这是第一个!
© . All rights reserved.