打开APP
userphoto
未登录

开通VIP,畅享免费电子书等14项超值服

开通VIP
基于MFC的OpenGL应用程序之环境搭建

基于MFCOpenGL应用程序

 

一:配置环境

 

 1. Windows环境下的GLUT下载地址:(大小约为150k)

     http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip    

2.  将下载的压缩包解开,将得到5个文件(glut.dll, glut32.dll, glut.lib, glut32.lib,glut.h)

 (1)把glut.h文件拉到C:\Program Files\Microsoft SDKs\Windows\v7.0A\Include\gl文   件夹下   

 (2)将glut.dll放到C:\WINDOWS\system32文件夹下

 (3)将glut32.dll 放到C:\Program Files\Microsoft Visual Studio 10.0\VC\bin文件夹下,

 (4)将glut.lib,glut32.lib 放到C:\Program Files\Microsoft Visual Studio 10.0\VC\lib文 件夹

3. 创建一个MFC SDI单文档应用程序-àZzw

4.  右击工程名Zzw-àProperty-àLinkeràinputàAdditional   Dependencies在此处加入链接库opengl32.lib;  glu32.lib;  glut32.lib; (注意用分号隔开)。

 

二:绘图 

1.在stdafx.h中加入下列语句:

//OpenGL Headers
#include
#include
#include

 

2.添加消息

右击CzzwView类àClassWizard-àMessages-à添加下面四个消息:

       ON_WM_CREATE()

       ON_WM_DESTROY()

       ON_WM_SIZE()

       ON_WM_ERASEBKGND()

 

3.设置窗口格式

    在窗口创建之前我们必须设置窗口风格包含WS_CLIPCHILDREN和 WS_CLIPSIBLINGS,从而避免OpenGL绘制到其他窗口中去。这些应该放在ZzwView.cpp的PreCreateWindow()中。 

BOOL CZzwView::PreCreateWindow(CREATESTRUCT& cs)
{
cs.style |= WS_CLIPSIBLINGS | WS_CLIPCHILDREN;
return CView::PreCreateWindow(cs);
}

 

4.添加自定义成员

 在ZzwView.h中加入如下语句:

HGLRC m_hRC; //Rendering Context
CDC* m_pDC; //Device Context
BOOL InitializeOpenGL(); //Initialize OpenGL
BOOL SetupPixelFormat(); //Set up the Pixel Format
void RenderScene(); //Render the Scene

 

5.  在OnCreate中我们将通过建立像素格式和绘制上下文来初始化OpenGL. 在InitializeOpenGL()中会创建一个设备上下文(DC),为这个DC选择一个像素格式,创建和这个DC相关的绘制上下文(RC),然后选择这个RC.这个函数会调用SetupPixelFormat()来建立像素格式。

int CZzwView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
//Initialize OpenGL Here
InitializeOpenGL();
return 0;
}

BOOL CZzwView::InitializeOpenGL()
{
//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;
}
//Specify Black as the clear color
::glClearColor(0.0f,0.0f,0.0f,0.0f);
//Specify the back of the buffer as clear depth
::glClearDepth(1.0f);
//Enable Depth Testing
::glEnable(GL_DEPTH_TEST);
return TRUE;
}

//Setup Pixel Format
/////////////////////////////////////////////////////////////////////////////
BOOL CZzwView::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
16,                                  // 16-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 )
{
return FALSE;
}
if ( ::SetPixelFormat(m_pDC->GetSafeHdc(), m_nPixelFormat, &pfd) == FALSE)
{
return FALSE;
}
return TRUE;
}

 

6.在OnSize()中一般用来设置视口和视维,因为这些是和窗口大小相关的。基本操作包括设置视口,选择投影矩阵,设置模型视图矩阵。

void CZzwView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
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
aspect_ratio = (GLdouble)cx/(GLdouble)cy;
// select the projection matrix and clear it
::glMatrixMode(GL_PROJECTION);
::glLoadIdentity();
// select the viewing volume

//::gluPerspective(45.0f, aspect_ratio, .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();
}

 

7.在绘制场景时,一般包括如下步骤:1)清空缓存。2)绘制场景。3)Flush掉渲染流水线。4)若设置了双缓冲,则交换前后台缓冲区。

// CZzwView drawing

void CZzwView::OnDraw(CDC* )

{

            CZzwDoc* pDoc = GetDocument();

            ASSERT_VALID(pDoc);

            if (!pDoc)

              return;

              RenderScene();

            // TODO: add draw code for native data here

}

 void CZzwView::RenderScene()

 {

 

       glClearColor(0.0f, 0.0f, 0.0f, 1.0f);

       glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);

       glBegin(GL_QUAD_STRIP);

                                   

       glVertex2f(-0.5f, 0.5f);

       glVertex2f(-0.5f, -0.5f);

       glVertex2f(0.5f, 0.5f);

       glVertex2f(0.5f, -0.5f);

       glEnd();

       glFinish();

       SwapBuffers(wglGetCurrentDC());

           

 }

 

8.试试改变窗口的大小,你会看到很严重的闪烁,并且关闭程序后会报告内存泄露,因此我们这就来解决这两个问题吧。

发生闪烁的原因是Windows先绘制背景,然后再是OpenGL绘制,因为我们已经让OpenGL负责清空背景色,因此我们不需要Windows去清空背景了.

把return CView::OnEraseBkgnd(pDC)改为 return TRUE;

BOOL CZzwView::OnEraseBkgnd(CDC* pDC)
{
   //Tell Windows not to erase the background

   //return CView::OnEraseBkgnd(pDC);
   return TRUE;
}

内存泄露的原因是我们在SetupPixelFormat()中使用了new运算符来为CClientDC对象分配内存,因此需要显示delete掉。

 

void CZzwView::OnDestroy()
{
   CView::OnDestroy();
  //Make the RC non-current
if(::wglMakeCurrent (0,0) == FALSE)
{
  return ;

}

//Delete the rendering context
if(::wglDeleteContext (m_hRC)==FALSE)
{
  return ;

}
//Delete the DC
if(m_pDC)
{
delete m_pDC;
}
//Set it to NULL
m_pDC = NULL;
}

以上就使用OpenGL绘制一个二维矩形了。

本站仅提供存储服务,所有内容均由用户发布,如发现有害或侵权内容,请点击举报
打开APP,阅读全文并永久保存 查看更多类似文章
猜你喜欢
类似文章
【热】打开小程序,算一算2024你的财运
OpenGL游戏学习一:MFC下OpenGL环境的搭建
OpenGL(非常值得借鉴)
MFC单文档程序中搭建OpenGL框架
基于MFC的OpenGL 绘图例程
基于MFC下的OpenGL框架
8《高效学习OpenGL》之 openGL设置窗口像素格式
更多类似文章 >>
生活服务
热点新闻
分享 收藏 导长图 关注 下载文章
绑定账号成功
后续可登录账号畅享VIP特权!
如果VIP功能使用有故障,
可点击这里联系客服!

联系客服