CSDN首页 空间 新闻 论坛 Blog 下载 读书 网摘 搜索 .NET Java 视频 接项目 求职 在线学习 买书 程序员 通知
IBM Rational 系统开发最佳实践工具包 WebSphere MQ 最佳实践 TOP 15
CSDN社区
搜索 收藏 打印 关闭
CSDN社区 >  VC/MFC >  图形处理/算法

在基于单文档的OpenGL框架中,怎样用鼠标实现物体的平移,旋转,缩放功能?

楼主lcg2008(天地乾坤)2006-03-14 11:19:32 在 VC/MFC / 图形处理/算法 提问

开始学习OpenGL,要实现以上功能,感觉真困难!在网上搜索了,根据一些资料,  
  还是实现不了,望高手给点指导,可否贴点代码出来啊?谢谢了!! 问题点数:100、回复次数:15Top

1 楼syy64(太平洋)回复于 2006-03-14 11:40:21 得分 50

#include   <windows.h>//   Header   File   For   Windows  
  #include   <stdio.h>//   Header   File   For   Standard   Input/Output  
  #include   <gl\gl.h>//   Header   File   For   The   OpenGL32   Library  
  #include   <gl\glu.h>//   Header   File   For   The   GLu32   Library  
  #include   <gl\glut.h>  
  #include   <gl\glaux.h>//   Header   File   For   The   Glaux   Library  
   
   
  static   GLfloat   spin   =   0.0;  
   
  HGLRC   hRC=NULL;    
  HDC   hDC=NULL;    
  HWND   hWnd=NULL;    
  HINSTANCE   hInstance;    
   
  BOOL   keys[256];    
  BOOL   active=TRUE;    
  BOOL   fullscreen=TRUE;    
   
  GLfloat   xrot;  
  GLfloat   yrot;  
  GLfloat   zrot;  
   
  GLuint   texture[1];  
   
  LRESULT   CALLBACK   WndProc(HWND,   UINT,   WPARAM,   LPARAM);    
   
  AUX_RGBImageRec   *LoadBMP(char   *Filename)  
  {  
  FILE   *File=NULL;    
  if   (!Filename)    
  {  
  return   NULL;    
  }  
  File=fopen(Filename,"r");    
  if   (File)    
  {  
  fclose(File);  
  return   auxDIBImageLoad(Filename);    
  }  
  return   NULL;  
  }  
  int   LoadGLTextures()    
  {  
  int   Status=FALSE;  
  AUX_RGBImageRec   *TextureImage[1];  
  memset(TextureImage,0,sizeof(void   *)*1);  
  if   (TextureImage[0]=LoadBMP("Data/NeHe.bmp"))  
  {  
  Status=TRUE;    
  glGenTextures(1,   &texture[0]);    
                  glBindTexture(GL_TEXTURE_2D,   texture[0]);  
  glTexImage2D(GL_TEXTURE_2D,   0,   3,   TextureImage[0]->sizeX,   TextureImage[0]->sizeY,   0,    
  GL_RGB,   GL_UNSIGNED_BYTE,   TextureImage[0]->data);  
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_LINEAR);    
  glTexParameteri(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_LINEAR);    
  }  
  if   (TextureImage[0])  
  {  
  if   (TextureImage[0]->data)    
  {  
  free(TextureImage[0]->data);  
  }  
   
  free(TextureImage[0]);  
  }  
  return   Status;    
  }  
  int   InitGL(GLvoid)  
  {  
  if   (!LoadGLTextures())    
  {  
  return   FALSE;    
  }  
   
  glEnable(GL_TEXTURE_2D);    
  glShadeModel(GL_SMOOTH);    
  glClearColor(0.0f,   0.0f,   0.0f,   0.5f);    
  glClearDepth(1.0f);    
  glEnable(GL_DEPTH_TEST);    
  glDepthFunc(GL_LEQUAL);    
  glHint(GL_PERSPECTIVE_CORRECTION_HINT,   GL_NICEST);    
  return   TRUE;      
  }  
   
   
  void   display(void)  
  {  
        glClear(GL_COLOR_BUFFER_BIT   |   GL_DEPTH_BUFFER_BIT);    
        glPushMatrix();      
        glBindTexture(GL_TEXTURE_2D,   texture[0]);                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                                        
        glRotatef(spin,   1.0,   10.0,   1.0);  
        glBegin(GL_QUADS);  
        glColor3f(0.0f,1.0f,0.0f);   //   颜色改为蓝色  
  glTexCoord2f(0.0f,   0.0f);       glVertex3f(   10.0f,   10.0f,-10.0f);   //   四边形的右上顶点   (顶面)  
  glTexCoord2f(1.0f,   0.0f);       glVertex3f(-10.0f,   10.0f,-10.0f);   //   四边形的左上顶点   (顶面)  
  glTexCoord2f(1.0f,   1.0f);       glVertex3f(-10.0f,   10.0f,   10.0f);   //   四边形的左下顶点   (顶面)  
  glTexCoord2f(0.0f,   1.0f);       glVertex3f(   10.0f,   10.0f,   10.0f);   //   四边形的右下顶点   (顶面)  
   
        glColor3f(1.0f,0.5f,0.0f);   //   颜色改成橙色  
  glTexCoord2f(1.0f,   0.0f);       glVertex3f(   10.0f,-10.0f,   10.0f);   //   四边形的右上顶点(底面)  
  glTexCoord2f(1.0f,   1.0f);       glVertex3f(-10.0f,-10.0f,   10.0f);   //   四边形的左上顶点(底面)  
  glTexCoord2f(0.0f,   1.0f);       glVertex3f(-10.0f,-10.0f,-10.0f);   //   四边形的左下顶点(底面)  
  glTexCoord2f(0.0f,   0.0f);       glVertex3f(   10.0f,-10.0f,-10.0f);   //   四边形的右下顶点(底面)  
   
        glColor3f(1.0f,0.0f,0.0f);   //   颜色改成红色  
  glTexCoord2f(0.0f,   1.0f);       glVertex3f(   10.0f,   10.0f,   10.0f);   //   四边形的右上顶点(前面)  
  glTexCoord2f(0.0f,   0.0f);       glVertex3f(-10.0f,   10.0f,   10.0f);   //   四边形的左上顶点(前面)  
  glTexCoord2f(1.0f,   0.0f);       glVertex3f(-10.0f,-10.0f,   10.0f);   //   四边形的左下顶点(前面)  
  glTexCoord2f(1.0f,   1.0f);       glVertex3f(   10.0f,-10.0f,   10.0f);   //   四边形的右下顶点(前面)  
   
        glColor3f(1.0f,1.0f,0.0f);   //   颜色改成黄色  
  glTexCoord2f(1.0f,   1.0f);       glVertex3f(   10.0f,-10.0f,-10.0f);   //   四边形的右上顶点(后面)  
  glTexCoord2f(0.0f,   1.0f);       glVertex3f(-10.0f,-10.0f,-10.0f);   //   四边形的左上顶点(后面)  
  glTexCoord2f(0.0f,   0.0f);       glVertex3f(-10.0f,   10.0f,-10.0f);   //   四边形的左下顶点(后面)  
  glTexCoord2f(1.0f,   0.0f);       glVertex3f(   10.0f,   10.0f,-10.0f);   //   四边形的右下顶点(后面)  
   
        glColor3f(0.0f,1.0f,1.0f);   //   颜色改成蓝色  
  glTexCoord2f(1.0f,   0.0f);       glVertex3f(-10.0f,   10.0f,   10.0f);   //   四边形的右上顶点(左面)  
  glTexCoord2f(1.0f,   1.0f);       glVertex3f(-10.0f,   10.0f,-10.0f);   //   四边形的左上顶点(左面)  
  glTexCoord2f(0.0f,   1.0f);       glVertex3f(-10.0f,-10.0f,-10.0f);   //   四边形的左下顶点(左面)  
  glTexCoord2f(0.0f,   0.0f);       glVertex3f(-10.0f,-10.0f,   10.0f);   //   四边形的右下顶点(左面)  
   
        glColor3f(1.0f,0.0f,1.0f);   //   颜色改成紫罗兰色  
  glTexCoord2f(0.0f,   0.0f);       glVertex3f(   10.0f,   10.0f,-10.0f);   //   四边形的右上顶点(右面)  
  glTexCoord2f(1.0f,   0.0f);       glVertex3f(   10.0f,   10.0f,   10.0f);   //   四边形的左上顶点(右面)  
  glTexCoord2f(1.0f,   1.0f);       glVertex3f(   10.0f,-10.0f,   10.0f);   //   四边形的左下顶点(右面)  
  glTexCoord2f(0.0f,   1.0f);       glVertex3f(   10.0f,-10.0f,-10.0f);   //   四边形的右下顶点(右面)  
        glEnd();      
         
         
        glPopMatrix();  
   
        glutSwapBuffers();  
  }  
   
  void   spinDisplay(void)  
  {  
        spin   =   spin   +   1.0;  
        if   (spin   >   360.0)  
              spin   =   spin   -   360.0;  
        glutPostRedisplay();  
  }  
   
   
  void   init(void)    
  {  
        glClearColor   (1.1,   1.0,   1.0,   1.0);  
        glShadeModel   (GL_SMOOTH);  
  }  
  void   keyboard(unsigned   char   key,   int   x,   int   y)  
  {  
  switch   (key)   {  
  case   27:  
  glutIdleFunc(spinDisplay);  
  //exit(0);  
  break;  
  case   '   ':  
  glutIdleFunc(NULL);  
  break;  
  default:  
  break;  
   
  }  
  }  
   
   
  void   reshape(int   w,   int   h)  
  {  
  glViewport   (0,   0,   (GLsizei)   w,   (GLsizei)   h);  
  glMatrixMode(GL_PROJECTION);  
  glLoadIdentity();  
  glOrtho(-50.0,   50.0,   -50.0,   50.0,   -100.0,   100.0);  
  glMatrixMode(GL_MODELVIEW);  
  glLoadIdentity();  
  }  
   
   
     
  void   mouse(int   button,   int   state,   int   x,   int   y)    
  {  
        switch   (button)   {  
              case   GLUT_LEFT_BUTTON:  
                    if   (state   ==   GLUT_DOWN)  
                          glutIdleFunc(spinDisplay);  
                    break;  
              case   GLUT_MIDDLE_BUTTON:  
              case   GLUT_RIGHT_BUTTON:  
                    if   (state   ==   GLUT_DOWN)  
                          glutIdleFunc(NULL);  
                    break;  
              default:  
                    break;  
        }  
  }  
   
         
  /*    
    *     Request   double   buffer   display   mode.  
    *     Register   mouse   input   callback   functions  
    */  
  int   main(int   argc,   char**   argv)  
  {  
        glutInit(&argc,   argv);  
        glutInitDisplayMode   (GLUT_DOUBLE   |   GLUT_RGB);  
        glutInitWindowSize   (800,   800);    
        glutInitWindowPosition   (100,   100);  
        glutCreateWindow   (argv[0]);  
        InitGL();  
        init   ();  
        glutDisplayFunc(display);    
        glutKeyboardFunc(keyboard);  
        glutReshapeFunc(reshape);    
        glutMouseFunc(mouse);  
        glutMainLoop();  
        return   0;       /*   ANSI   C   requires   main   to   return   int.   */  
  }  
  Top

2 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2006-03-14 12:14:33 得分 30

opengl里面这些操作都是通过变换矩阵来实现的  
   
  你可以用参数来控制的生成,这些参数就是,位置,比例和姿态(也就是你要做的移动,缩放和旋转)  
  鼠标如何控制的参数是你的界面UI的问题  
  根据这些参数的具体数值在显示前实时的生成world矩阵,就达到目的了  
   
  Top

3 楼besomethingbig(一个人的夏天)回复于 2006-03-14 20:02:50 得分 20

你应该已经定义了物体的平移,旋转,和缩放等需要的参数,把它们在类中声明成员变量,使它们在类中所有模块都有效。这样在鼠标位置发生改变的时候,通过位置变化改变物体的几何参数,然后调用绘制函数,就可以实现物体的变换了  
  小例子  
  定义了物体位置参数  
   
  在View类声明成员函数   CPoint   MouseDownPoint;//记录鼠标的位置信息  
  GLfloat   m_fCorX;  
  GLfloat   m_fCorY;  
   
  初始化   m_fCorX;  
                m_fCorY;  
   
  在下面三个函数中填写代码  
  void   CDialog_3D::OnLButtonDown(UINT   nFlags,   CPoint   point)    
  {  
  //   TODO:   Add   your   message   handler   code   here   and/or   call   default  
  //   remember   where   we   clicked  
  MouseDownPoint=point;//记录当前点  
  //   capture   mouse   movements   even   outside   window   borders  
  SetCapture();//捕获  
   
  CDialog::OnLButtonDown(nFlags,   point);  
  }  
   
  void   CDialog_3D::OnLButtonUp(UINT   nFlags,   CPoint   point)    
  {  
  //   TODO:   Add   your   message   handler   code   here   and/or   call   default  
  //   forget   where   we   clicked  
  MouseDownPoint=CPoint(0,0);//清空位置信息  
  //   release   mouse   capture  
  ReleaseCapture();//释放捕获  
   
  CDialog::OnLButtonUp(nFlags,   point);  
  }  
   
  void   CDialog_3D::OnMouseMove(UINT   nFlags,   CPoint   point)    
  {  
  //   TODO:   Add   your   message   handler   code   here   and/or   call   default  
  //   check   if   we   have   captured   the   mouse  
   
  if   (GetCapture()==this)  
  {  
  if(nFlags&MK_CONTROL)//如果Ctrl按下了  
  {  
  m_fCorX+=double(point.x-MouseDownPoint.x);  
  m_fCorY+=double(MouseDownPoint.y-point.y);  
  OnPaint();//重绘  
  //   remember   the   mouse   point  
  MouseDownPoint=point;//保留当前点  
  }  
  }  
  CDialog::OnMouseMove(nFlags,   point);  
  }  
   
   
  在OnDraw函数中,在绘制图形时,用m_fCorX和m_fCorY来控制物体的位置,这样当鼠标拖动时就会发出绘制命令,实现物体的变换  
   
  //我也是个出学者,请高手把更好的方法贡献出来,谢谢Top

4 楼lcg2008(天地乾坤)回复于 2006-03-16 09:10:55 得分 0

谢谢这么多好人的回答!!!  
  但是在多个物体时,我想应该先是选中某个物体吧?再在此基础上实行移动,旋转,放缩吧?  
  那选中物体是怎样判断和实现啊?  
  再次谢谢!!Top

5 楼syy64(太平洋)回复于 2006-03-16 09:13:14 得分 0

用OpenGL选择模式。Top

6 楼besomethingbig(一个人的夏天)回复于 2006-03-16 09:44:18 得分 0

syy64(太平洋),我对楼主的第二个问题也很感兴趣,能否描述的详细一点,谢谢Top

7 楼lcg2008(天地乾坤)回复于 2006-03-16 12:09:45 得分 0

到处寻找资料,组合成了一个东东,能够勉强实现选中一个物体实现移动(代码中的蓝色的earth),但还是有点问题:(1)拖动过程中,圆形的earth变形了,成为了椭圆形之类。  
                                                    (2)earth跟鼠标不是完全贴在一起移动。  
                                                    (3)如何让鼠标选中earth后,鼠标由箭头形变成手指形。    
  请syy64(太平洋),happy_888([顾问团]寻开心)等大侠帮帮忙啊?谢谢!!Top

8 楼lcg2008(天地乾坤)回复于 2006-03-16 12:11:16 得分 0

//   Test_1View.cpp   :   implementation   of   the   CTest_1View   class  
  //  
   
  #include   "stdafx.h"  
  #include   "Test_1.h"  
   
  #include   "Test_1Doc.h"  
  #include   "Test_1View.h"  
   
  #ifdef   _DEBUG  
  #define   new   DEBUG_NEW  
  #undef   THIS_FILE  
  static   char   THIS_FILE[]   =   __FILE__;  
  #endif  
  ///////////////////////////////  
  //   Define   object   names  
  #define   EARTH 1  
  #define   MARS 2  
  #define   MOON1 3  
  #define   MOON2 4  
  ////////////////////////////////  
  //define   the   global   variable  
   
  GLfloat   m_fCorX=-100.0f;  
  GLfloat   m_fCorY=0.0f;  
  bool   istrue;  
   
   
  /////////////////////////////////////////////////////////////////////////////  
  //   CTest_1View  
   
  IMPLEMENT_DYNCREATE(CTest_1View,   CView)  
   
  BEGIN_MESSAGE_MAP(CTest_1View,   CView)  
  //{{AFX_MSG_MAP(CTest_1View)  
  ON_WM_CREATE()  
  ON_WM_DESTROY()  
  ON_WM_ERASEBKGND()  
  ON_WM_SIZE()  
  ON_WM_LBUTTONDOWN()  
  ON_WM_MOUSEMOVE()  
  ON_WM_LBUTTONUP()  
  //}}AFX_MSG_MAP  
  //   Standard   printing   commands  
  ON_COMMAND(ID_FILE_PRINT,   CView::OnFilePrint)  
  ON_COMMAND(ID_FILE_PRINT_DIRECT,   CView::OnFilePrint)  
  ON_COMMAND(ID_FILE_PRINT_PREVIEW,   CView::OnFilePrintPreview)  
  END_MESSAGE_MAP()  
   
  /////////////////////////////////////////////////////////////////////////////  
  //   CTest_1View   construction/destruction  
   
  CTest_1View::CTest_1View()  
  {  
  //   TODO:   add   construction   code   here  
   
  }  
   
  CTest_1View::~CTest_1View()  
  {  
  }  
   
  BOOL   CTest_1View::PreCreateWindow(CREATESTRUCT&   cs)  
  {  
  //   TODO:   Modify   the   Window   class   or   styles   here   by   modifying  
  //     the   CREATESTRUCT   cs  
          cs.style   |=   WS_CLIPSIBLINGS   |   WS_CLIPCHILDREN   |   CS_OWNDC;  
  return   CView::PreCreateWindow(cs);  
  }  
   
  /////////////////////////////////////////////////////////////////////////////  
  //   CTest_1View   drawing  
   
  void   CTest_1View::OnDraw(CDC*   pDC)  
  {  
  CTest_1Doc*   pDoc   =   GetDocument();  
  ASSERT_VALID(pDoc);  
  //   TODO:   add   draw   code   for   native   data   here  
  ///////////////////////////////////////////////////////////////////////  
  myDrawScene(   );                                                     //具体的绘图函数,在   RC   中绘制  
          ///////////////////////////////////////////////////////////////////////  
  }  
   
  /////////////////////////////////////////////////////////////////////////////  
  //   CTest_1View   printing  
   
  BOOL   CTest_1View::OnPreparePrinting(CPrintInfo*   pInfo)  
  {  
  //   default   preparation  
  return   DoPreparePrinting(pInfo);  
  }  
   
  void   CTest_1View::OnBeginPrinting(CDC*   /*pDC*/,   CPrintInfo*   /*pInfo*/)  
  {  
  //   TODO:   add   extra   initialization   before   printing  
  }  
   
  void   CTest_1View::OnEndPrinting(CDC*   /*pDC*/,   CPrintInfo*   /*pInfo*/)  
  {  
  //   TODO:   add   cleanup   after   printing  
  }  
   
  /////////////////////////////////////////////////////////////////////////////  
  //   CTest_1View   diagnostics  
   
  #ifdef   _DEBUG  
  void   CTest_1View::AssertValid()   const  
  {  
  CView::AssertValid();  
  }  
   
  void   CTest_1View::Dump(CDumpContext&   dc)   const  
  {  
  CView::Dump(dc);  
  }  
   
  CTest_1Doc*   CTest_1View::GetDocument()   //   non-debug   version   is   inline  
  {  
  ASSERT(m_pDocument->IsKindOf(RUNTIME_CLASS(CTest_1Doc)));  
  return   (CTest_1Doc*)m_pDocument;  
  }  
  #endif   //_DEBUG  
   
  /////////////////////////////////////////////////////////////////////////////  
  //   CTest_1View   message   handlers  
   
  int   CTest_1View::OnCreate(LPCREATESTRUCT   lpCreateStruct)    
  {  
  if   (CView::OnCreate(lpCreateStruct)   ==   -1)  
  return   -1;  
   
  //   TODO:   Add   your   specialized   creation   code   here  
  myInitOpenGL();  
  return   0;  
  }  
   
  void   CTest_1View::myInitOpenGL()  
  {  
  m_pDC   =   new   CClientDC(this);   //创建   DC  
          ASSERT(m_pDC   !=   NULL);    
          if   (!mySetupPixelFormat())   //设定绘图的位图格式,函数下面列出  
                  return;    
          m_hRC   =   wglCreateContext(m_pDC->m_hDC);//创建   RC  
          wglMakeCurrent(m_pDC->m_hDC,   m_hRC);   //RC   与当前   DC   相关联  
          //   Lighting   values  
  GLfloat     dimLight[]   =   {   0.1f,   0.1f,   0.1f,   1.0f   };  
  GLfloat     sourceLight[]   =   {   0.65f,   0.65f,   0.65f,   1.0f   };  
  GLfloat   lightPos[]   =   {   0.0f,   0.0f,   0.0f,   1.0f   };  
   
  //   Light   values   and   coordinates  
  glEnable(GL_DEPTH_TEST); //   Hidden   surface   removal  
  glFrontFace(GL_CCW); //   Counter   clock-wise   polygons   face   out  
  glEnable(GL_CULL_FACE); //   Do   not   calculate   insides  
   
  //   Enable   lighting  
  glEnable(GL_LIGHTING);  
   
  //   Setup   and   enable   light   0  
  glLightfv(GL_LIGHT0,   GL_AMBIENT,   dimLight);  
  glLightfv(GL_LIGHT0,GL_DIFFUSE,sourceLight);  
  glLightfv(GL_LIGHT0,GL_POSITION,lightPos);  
  glEnable(GL_LIGHT0);  
   
  //   Enable   color   tracking  
  glEnable(GL_COLOR_MATERIAL);  
   
  //   Set   Material   properties   to   follow   glColor   values  
  glColorMaterial(GL_FRONT,   GL_AMBIENT_AND_DIFFUSE);  
   
  //   Gray   background  
  glClearColor(1.0f,   0.20f,   0.80f,   1.0f   );  
  }  
   
  BOOL   CTest_1View::mySetupPixelFormat()  
  {  
  static   PIXELFORMATDESCRIPTOR   pfd   ={  
  sizeof(PIXELFORMATDESCRIPTOR),   //   size   of   this   pfd  
  1,                                                           //   version   number  
  PFD_DRAW_TO_WINDOW   |                       //   support   window  
  PFD_SUPPORT_OPENGL   |                       //   support   OpenGL  
  PFD_DOUBLEBUFFER,                             //   double   buffered  
  PFD_TYPE_RGBA,                                   //   RGBA   type  
  24,                                                         //   24-bit   color   depth  
  0,   0,   0,   0,   0,   0,                             //   color   bits   ignored  
  0,                                                           //   no   alpha   buffer  
  0,                                                           //   shift   bit   ignored  
  0,                                                           //   no   accumulation   buffer  
  0,   0,   0,   0,                                         //   accum   bits   ignored  
  32,                                                         //   32-bit   z-buffer  
  0,                                                           //   no   stencil   buffer  
  0,                                                           //   no   auxiliary   buffer  
  PFD_MAIN_PLANE,                                 //   main   layer  
  0,                                                           //   reserved  
  0,   0,   0                                                 //   layer   masks   ignored  
  };    
  int   pixelformat;    
  if   (   (pixelformat   =   ChoosePixelFormat(m_pDC->m_hDC,   &pfd))   ==   0   )  
  {  
  MessageBox("ChoosePixelFormat   failed");  
  return   FALSE;  
  }    
  if   (SetPixelFormat(m_pDC->m_hDC,   pixelformat,   &pfd)   ==   FALSE)  
  {  
  MessageBox("SetPixelFormat   failed");  
  return   FALSE;  
  }    
  return   TRUE;  
  }  
   
  void   CTest_1View::OnDestroy()    
  {  
  CView::OnDestroy();  
   
  //   TODO:   Add   your   message   handler   code   here  
  wglMakeCurrent(m_pDC->m_hDC,NULL);       //释放与m_hDC   对应的   RC  
  wglDeleteContext(m_hRC);                           //删除   RC    
          if   (m_pDC)  
  delete   m_pDC;                                         //删除当前   View   拥有的   DC    
  }  
   
   
  Top

9 楼lcg2008(天地乾坤)回复于 2006-03-16 12:11:47 得分 0

接着上面的  
  BOOL   CTest_1View::OnEraseBkgnd(CDC*   pDC)    
  {  
  //   TODO:   Add   your   message   handler   code   here   and/or   call   default  
  return   TRUE;//只要空返回即可  
  //return   CView::OnEraseBkgnd(pDC);  
  }  
   
  void   CTest_1View::myDrawScene()  
  {  
  //   Clear   the   window   with   current   clearing   color  
  glClear(GL_COLOR_BUFFER_BIT   |   GL_DEPTH_BUFFER_BIT);  
   
   
  //   Save   the   matrix   state   and   do   the   rotations  
  glMatrixMode(GL_MODELVIEW);  
  glPushMatrix();  
   
  //   Translate   the   whole   scene   out   and   into   view  
  glTranslatef(0.0f,   0.0f,   -300.0f);  
   
  //   Initialize   the   names   stack  
  glInitNames();  
  glPushName(0);  
   
   
  //   Draw   the   Earth  
  glPushMatrix();  
  glColor3f(0.0f,   0.0f,   1.0f);  
  //glTranslatef(-100.0f,0.0f,0.0f);  
  glTranslatef(m_fCorX,m_fCorY,0.0f);  
  glLoadName(EARTH);  
  DrawSphere(30.0f);  
  glPopMatrix();  
   
  //   Draw   the   Moon  
  glPushMatrix();  
  glTranslatef(45.0f,   0.0f,   0.0f);  
  glColor3f(0.85f,   0.85f,   0.85f);  
  glLoadName(MOON1);  
  DrawSphere(5.0f);  
  glPopName();  
  glPopMatrix();  
   
  //   Draw   Mars  
  glColor3f(1.0f,   0.0f,   0.0f);  
  glPushMatrix();  
  glTranslatef(100.0f,   0.0f,   0.0f);  
  glLoadName(MARS);  
  DrawSphere(20.0f);  
   
  //   Draw   Moon1  
  glTranslatef(-40.0f,   40.0f,   0.0f);  
  glColor3f(0.85f,   0.85f,   0.85f);  
  glPushName(MOON1);  
  DrawSphere(5.0f);  
  glPopName();  
   
  //   Draw   Moon2  
  glTranslatef(0.0f,   -80.0f,   0.0f);  
  glPushName(MOON2);  
  DrawSphere(5.0f);  
  glPopName();  
  glPopMatrix();  
   
  //   Restore   the   matrix   state  
  glPopMatrix(); //   Modelview   matrix  
  ::SwapBuffers(m_pDC->GetSafeHdc());  
  }  
   
  void   CTest_1View::OnSize(UINT   nType,   int   cx,   int   cy)    
  {  
  CView::OnSize(nType,   cx,   cy);  
  w=cx;  
  h=cy;  
  GLfloat   fAspect; //   Screen   aspect   ratio  
   
  //   Prevent   a   divide   by   zero  
  if(h   ==   0)  
  h   =   1;  
   
  //   Set   Viewport   to   window   dimensions  
          glViewport(0,   0,   w,   h);  
   
  //   Calculate   aspect   ratio   of   the   window  
  fAspect   =   (GLfloat)w/(GLfloat)h;  
   
  //   Set   the   perspective   coordinate   system  
  glMatrixMode(GL_PROJECTION);  
  glLoadIdentity();  
   
  //   Field   of   view   of   45   degrees,   near   and   far   planes   1.0   and   425  
  gluPerspective(45.0f,   fAspect,   1.0,   425.0);  
   
  //   Modelview   matrix   reset  
  glMatrixMode(GL_MODELVIEW);  
  glLoadIdentity();  
  }  
  void   CTest_1View::OnLButtonDown(UINT   nFlags,   CPoint   point)    
  {  
  //   TODO:   Add   your   message   handler   code   here   and/or   call   default  
  CView::OnLButtonDown(nFlags,   point);  
  ProcessSelection(point.x,   point.y);  
  //   remember   where   we   clicked  
          MouseDownPoint=point;//记录当前点  
          //   capture   mouse   movements   even   outside   window   borders  
          SetCapture();//捕获  
   
  }  
   
   
  void   CTest_1View::DrawSphere(float   radius)  
  {  
  GLUquadricObj   *pObj;  
  pObj   =   gluNewQuadric();  
  gluQuadricNormals(pObj,   GLU_SMOOTH);  
  gluSphere(pObj,   radius,   26,   13);  
  gluDeleteQuadric(pObj);  
  }  
  #define   BUFFER_LENGTH   64  
  void   CTest_1View::ProcessSelection(int   xPos,   int   yPos)  
  {  
  GLfloat   fAspect; //   Screen   aspect   ratio  
   
  //   Space   for   selection   buffer  
  GLuint   selectBuff[BUFFER_LENGTH];  
   
  //   Hit   counter   and   viewport   storeage  
  GLint   hits,   viewport[4];  
   
  //   Setup   selection   buffer  
  glSelectBuffer(BUFFER_LENGTH,   selectBuff);  
   
  //   Get   the   viewport  
  glGetIntegerv(GL_VIEWPORT,   viewport);  
   
  //   Switch   to   projection   and   save   the   matrix  
  glMatrixMode(GL_PROJECTION);  
  glPushMatrix();  
   
  //   Change   render   mode  
  glRenderMode(GL_SELECT);  
   
  glLoadIdentity();  
  gluPickMatrix(xPos,   viewport[3]   -   yPos,   2,2,   viewport);  
   
  //   Apply   perspective   matrix    
  fAspect   =   (float)viewport[2]   /   (float)viewport[3];  
  gluPerspective(45.0f,   fAspect,   1.0,   425.0);  
   
  //   Draw   the   scene  
  myDrawScene();  
   
  //   Collect   the   hits  
  hits   =   glRenderMode(GL_RENDER);  
   
  //   If   a   single   hit   occured,   display   the   info.  
  if(hits   ==   1)  
  ProcessPlanet(selectBuff);  
  //else  
  //MessageBox("You   clicked   empty   space!");  
   
  //   Restore   the   projection   matrix  
  glMatrixMode(GL_PROJECTION);  
  glPopMatrix();  
   
  //   Go   back   to   modelview   for   normal   rendering  
  glMatrixMode(GL_MODELVIEW);  
  }  
   
  void   CTest_1View::ProcessPlanet(GLuint   *pSelectBuff)  
  {  
  int   id,count;  
  char   cMessage[64];  
  strcpy(cMessage,"Error,   no   selection   detected");  
   
  //   How   many   names   on   the   name   stack  
  count   =   pSelectBuff[0];  
   
  //   Bottom   of   the   name   stack  
  id   =   pSelectBuff[3];  
   
  //   Select   on   earth   or   mars,   whichever   was   picked  
  switch(id)  
  {  
  case   EARTH:  
  //strcpy(cMessage,"You   clicked   Earth.");  
                            //   Draw   the   scene  
  istrue=true;  
  //   If   there   is   another   name   on   the   name   stack,  
  //   then   it   must   be   the   moon   that   was   selected  
  //   This   is   what   was   actually   clicked   on  
  if(count   ==   2)  
  strcat(cMessage,"   -   Specifically   the   moon.");  
   
  break;  
   
  case   MARS:  
  strcpy(cMessage,"You   clicked   Mars.");  
   
  //   We   know   the   name   stack   is   only   two   deep.   The   precise  
  //   moon   that   was   selected   will   be   here.  
  if(count   ==   2)  
  {  
  if(pSelectBuff[4]   ==   MOON1)  
  strcat(cMessage,"   -   Specifically   Moon   #1.");  
  else  
  strcat(cMessage,"   -   Specifically   Moon   #2.");  
  }  
  break;  
  }  
   
  //   Display   the   message   about   planet   and   moon   selection  
  //MessageBox(cMessage);  
  }  
   
  void   CTest_1View::OnMouseMove(UINT   nFlags,   CPoint   point)    
  {  
  //   TODO:   Add   your   message   handler   code   here   and/or   call   default  
  if   (GetCapture()==this)  
  {  
              if(istrue==true)//如果earth选中了  
      {          
    m_fCorX+=(point.x-MouseDownPoint.x);  
                    m_fCorY+=(MouseDownPoint.y-point.y);  
                    myDrawScene();//重绘  
                    //   remember   the   mouse   point  
                    MouseDownPoint=point;//保留当前点  
      }        
  }  
   
  CView::OnMouseMove(nFlags,   point);  
  }  
   
  void   CTest_1View::OnLButtonUp(UINT   nFlags,   CPoint   point)    
  {  
  //   TODO:   Add   your   message   handler   code   here   and/or   call   default  
  //KillTimer(0);  
  //LButtonDown=false;  
  //   forget   where   we   clicked  
          MouseDownPoint=CPoint(0,0);//清空位置信息  
          //   release   mouse   capture  
          ReleaseCapture();//释放捕获  
          istrue=false;  
  CView::OnLButtonUp(nFlags,   point);  
  }  
  Top

10 楼LG11(一句话)回复于 2006-03-16 20:19:50 得分 0

以上代码,我运行了一下,觉得有以下问题:  
                                (1)拖动过程中,圆形的earth变形了,成为了椭圆形之类。  
                                (2)earth跟鼠标不是完全贴在一起移动。  
  请问syy64(太平洋),happy_888([顾问团]寻开心)等大侠,这该怎样解决啊?谢谢!!Top

11 楼femalelover(楼主, 请把用不着的可用分捐给我1/3 :()回复于 2006-03-17 01:45:54 得分 0

选择模式的使用可能不是syy64,happy_888一两句能说清楚的.俺最近也正在学选择与反馈,汗啊,有难度.Top

12 楼lcg2008(天地乾坤)回复于 2006-03-17 08:53:38 得分 0

物体如(earth)不紧跟着鼠标一起移动,在屏幕正中时没有多大位差,可移动到屏幕边缘时鼠标与物体就有一段距离了,我想做到鼠标和选中的物体一起紧贴着移动,能够实现吗?怎样实现啊?谢谢了!Top

13 楼happy__888([顾问团]寻开心 www.e-jjj.com)回复于 2006-03-17 11:13:51 得分 0

1   变形最大的可能是你的控制矩阵搞错了,把移动的控制量作用到比例上  
  2   移动的时候,鼠标是在一个二维的平面内移动的,而你的物体是在三维的面内  
      要精确定位,就需要定位你的物体的移动面,并且计算移动平面和鼠标的交点  
      这个有些复杂,完整的说,还应该计算pick的时候,物体上的pick点的位置,然后把移动面太高到对应的位置去计算才能精确的  
  Top

14 楼femalelover(楼主, 请把用不着的可用分捐给我1/3 :()回复于 2006-03-17 14:57:46 得分 0

上面syy64给出的代码中没有这个函数glutInitWithExit   ,我拿那段代码编译的时候说这个函数无法解释,怎么回事?Top

15 楼syy64(太平洋)回复于 2006-03-17 16:47:21 得分 0

需要glut32.lib库。Top

相关问题

  • 关于平移物体的问题.
  • 关于在OPENGL中用鼠标移动物体
  • OPENGL的API及扩展函数的文档
  • 怎么在MFC中用OpenGL实现用鼠标拖动一个物体,以便从不同角度观察此物体?
  • 三维物体
  • 请教高手,如何使用OpenGL实现对不规则的三维物体进行包络?
  • 求救——OpenGL中关于射线法拾取物体表面点的问题(好难)
  • Datawindow To Word文档
  • .NET Framework 文档
  • 何谓"文档"?

关键词

  • 物体
  • 鼠标
  • 函数
  • view
  • 移动
  • 代码
  • ctest
  • 四边形
  • gl
  • textureimage

得分解答快速导航

  • 帖主:lcg2008
  • syy64
  • happy__888
  • besomethingbig

相关链接

  • Visual C++类图书
  • Visual C++类源码下载

广告也精彩

反馈

请通过下述方式给我们反馈
反馈
提问
网站简介|广告服务|VIP资费标准|银行汇款帐号|网站地图|帮助|联系方式|诚聘英才|English|问题报告
北京创新乐知广告有限公司 版权所有, 京 ICP 证 070598 号
世纪乐知(北京)网络技术有限公司 提供技术支持
Copyright © 2000-2008, CSDN.NET, All Rights Reserved
GongshangLogo