基于mfc的opengl怎么实现鼠标操控

Posted

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了基于mfc的opengl怎么实现鼠标操控相关的知识,希望对你有一定的参考价值。

参考技术A 你好,有需要的 了帮助你实现。

VC基于单文档opengl框架

本文是在VC6.0的环境下,运用MFC实现的OpenGL最基本框架,需要简单了解MFC编程(会在VC6.0里创建MFC单文档应用程序就行),甚至不必了解OpenGL的知识。以下是具体的步骤。

1、创建MFC单文档应用程序
2
、添加lib

Project->Setting->Link  添加"*.lib"  opengl32.lib glu32.lib glut32.lib glaux.lib

以上的lib文件需要存在于VC6.0安装好的目录下的lib文件夹底下,例如:

C:\Program Files\Microsoft Visual Studio\VC98\Lib

如果一些lib文件没有,可以去网上搜下,自己下载。

3、在stdafx.h中添加OpenGL头文件

//OpenGL Headers
#include <gl\gl.h>          //OpenGL32库的头文件
#include <gl\glu.h>         //GLu32库的头文件
#include <gl\glut.h>        //OpenGL实用库的头文件
#include <gl\glaux.h>       //GLaux库的头文件

以上的头文件需要存在于VC6.0安装好的目录下的Include下的GL文件夹下,例如:

C:\Program Files\Microsoft Visual Studio\VC98\Include\GL

如果一些头文件没有,可以去网上搜下,自己下载。

4、在MainFrame中设置程序标题、风格和窗口大小

cs.style = WS_OVERLAPPED | WS_CAPTION | WS_THICKFRAME | WS_SYSMENU |          
WS_MINIMIZEBOX | WS_MAXIMIZEBOX | WS_MAXIMIZE;
cs.lpszName = "OpenGL最基本框架";
//cs.cx = 500;
//cs.cy = 500;

5、设定OpenGL风格

CMyVIew中的PreCreateWindow中添加
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;

在客户区绘制

6、在CMyView中添加公有(public)成员变量

CClientDC *m_pDC;  //Device Context 设备上下文
HGLRC  m_hRC;      //Rendering Context 着色上下文
CRect  m_oldRect;
CString m_WindowTitle ; //窗口标题

7、在CMyView中添加保护(protected)成员函数
7.1、设置像素格式,即OpenGL怎样操作像素

BOOL CMyView::SetupPixelFormat()
{
 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 m_nPixelFormat = ::ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);
 if ( m_nPixelFormat == 0 )
 {
    MessageBox("ChoosePixelFormat failed.");
    return FALSE;
 }
 if ( ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)
 {
    MessageBox("SetPixelFormat failed.");
    return FALSE;
 }
    return TRUE;
}

7.2、创建着色描述表并当前化着色表

BOOL CMyView::InitOpenGL()
{
 //Get a DC for the Client Area
 m_pDC = new CClientDC(this);
 //Failure to Get DC
 if(m_pDC == NULL)
 {
  MessageBox("Error Obtaining DC");
  return FALSE;
 }
 //Failure to set the pixel format
 if(!SetupPixelFormat())
 {
  return FALSE;
 }
 //Create Rendering Context
 m_hRC = ::wglCreateContext (m_pDC->GetSafeHdc ());
 //Failure to Create Rendering Context
 if(m_hRC == 0)
 {
  MessageBox("Error Creating RC");
  return FALSE;
 }
 
 //Make the RC Current
 if(::wglMakeCurrent (m_pDC->GetSafeHdc (), m_hRC)==FALSE)
 {
  MessageBox("Error making RC Current");
  return FALSE;
 }
 //GetClientRect(&m_oldRect);
 // 启用阴影平滑
 ::glShadeModel(GL_SMOOTH);
 
 //黑色背景
 ::glClearColor(0.0f,0.0f,0.0f,0.0f);
 //设置深度缓存
 ::glClearDepth(1.0f);
 //启用深度测试
 ::glEnable(GL_DEPTH_TEST);
 //所作深度测试的类型
 ::glDepthFunc(GL_LEQUAL);   
 //告诉系统对透视进行修正
 ::glHint(GL_PERSPECTIVE_CORRECTION_HINT, GL_NICEST);  
 
 return TRUE;
}

7.3 删除着色表,响应WM_DESTROY消息

void CMyView::OnDestroy()
{
 CView::OnDestroy();
 //Delete the RC
 if(m_hRC)
 {
  //Make the RC non-current
  if(::wglMakeCurrent (NULL,NULL) == FALSE)
  {
   ::MessageBox(NULL,"释放DC或RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
  }
  //Delete the rendering context
  if(::wglDeleteContext (m_hRC)==FALSE)
  {
   ::MessageBox(NULL,"释放RC失败。","关闭错误",MB_OK | MB_ICONINFORMATION);
  }
    m_hRC = NULL;
 }
 
 //Delete the DC
 if(m_pDC)
 {
  delete m_pDC;
 }
 //Set it to NULL
 m_pDC = NULL;

8、响应WM_CREATE消息

int CMyView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
 if (CView::OnCreate(lpCreateStruct) == -1)
  return -1;
 
 GetParentFrame()->GetWindowText(m_WindowTitle);
 GetParentFrame()->ModifyStyle(FWS_ADDTOTITLE,0);
  
 if(!InitOpenGL())
 {
  ::MessageBox(NULL,"初始化OpenGL失败.","",MB_OK|MB_ICONEXCLAMATION);
  return -1;
 }
 return 0;
}

9、响应WM_SIZE消息

void CMyView::OnSize(UINT nType, int cx, int cy)
{
 CView::OnSize(nType, cx, cy);
 
 // TODO: Add your message handler code here
 if ( cx <= 0 || cy <= 0 )
 {
  return;
 }
 if((m_oldRect.right > cx) || (m_oldRect.bottom> cy))
 {
  RedrawWindow();
 }
 m_oldRect.right = cx;
 m_oldRect.bottom = cy;

 //选择投影矩阵
 ::glMatrixMode(GL_PROJECTION);
 //重置投影矩阵
       ::glLoadIdentity();
 //计算窗口的外观比例
 ::gluPerspective(45, (GLfloat)cx/(GLfloat)cy, 0.1f, 3.0*10e+11f);
 //设置模型观察矩阵
 ::glMatrixMode(GL_MODELVIEW);
 //重置模型观察矩阵
 ::glLoadIdentity();
 //::glFrustum(-1.0, 1.0, -1.0, 1.0, 0.0, 7.0);
 //设置当前的视口
 ::glViewport(0, 0, cx, cy);
}

10、绘制

void CMyView::DrawScene()
{
       glClearColor(0.0f, 0.0f, 0.0f, 1.0f);
       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
       glLoadIdentity();
       glColor3f(1.0f,0.0f,0.0f);
       glTranslatef(-1.5f,0.0f,-6.0f);
       glBegin(GL_TRIANGLES);              // 绘制三角形
       glVertex3f( 0.0f, 1.0f, 0.0f);       // 上顶点
       glVertex3f(-1.0f,-1.0f, 0.0f);       // 左下
       glVertex3f( 1.0f,-1.0f, 0.0f);       // 右下
    glEnd(); 
       SwapBuffers(wglGetCurrentDC());      
}

此后,各种绘制代码可以放入DrawScene()中,来扩充自己想要的功能。

11、在OnDraw()中调用DrawScene()

 

 

原文链接:

VC基于单文档opengl框架

以上是关于基于mfc的opengl怎么实现鼠标操控的主要内容,如果未能解决你的问题,请参考以下文章

如何在 C++/OpenGL 中获取当前鼠标位置?

用C++或者OpenGL或者Ogre实现鼠标移动轨迹

openGL按鼠标中键实现放大缩小

VC基于单文档opengl框架

openGL三维网格坐标,旋转,缩放,灯光设置,纹理读取,模型读取(MFC单文档)

opengl如何在MFC中设置双缓冲