基于MFC的OpenGL的一个简单例子

1.在VC6.0中新建MFC工程后,加入以下代码使得OpenGL的函数可以调用,最好加到StdAfx.h中 
#pragma   comment   (lib,   "glu32.lib")   
#pragma   comment   (lib,   "glaux.lib")   
#pragma   comment   (lib,   "Opengl32.lib") 
#pragma   comment   (lib,   "gdi32.lib") 
#pragma   comment   (lib,   "user32.lib") 
#pragma   comment   (lib,   "advapi32.lib") 
#include <GL/gl.h> 
#include <GL/glu.h> 
#include <GL/glaux.h>

注:VC6.0带了OpenGL所需的库及头文件,不需要另行安装 

2.将View类的PreCreateWindow函数中加入
cs.style |= (WS_CLIPCHILDREN | WS_CLIPSIBLINGS); 
OpenGL需要窗口加上WS_CLIPCHILDREN(创建父窗口使用的Windows风格,用于重绘时裁剪子窗口所覆盖的区域)和 WS_CLIPSIBLINGS(创建子窗口使用的Windows风格,用于重绘时剪裁其他子窗口所覆盖的区域)风格。

3.在View的类中添加一个保护型的成员函数bool SetWindowPixelFormat(HDC hDC)(用鼠标右键添加)和保护型的成员变量int m_GLPixelIndex;并在SetWindowPixelFormat中添加如下代码,相当于对OpenGL进行配置
    PIXELFORMATDESCRIPTOR pixelDesc=
    {
        sizeof(PIXELFORMATDESCRIPTOR),
        1,
        PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|
        PFD_DOUBLEBUFFER|PFD_SUPPORT_GDI,
        PFD_TYPE_RGBA,
        24,
        0,0,0,0,0,0,
        0,
        0,
        0,
        0,0,0,0,
        32,
        0,
        0,
        PFD_MAIN_PLANE,
        0,
        0,0,0
    };

    this->m_GLPixelIndex = ChoosePixelFormat(hDC,&pixelDesc);
    if(this->m_GLPixelIndex==0)
    {
        this->m_GLPixelIndex = 1;
        if(DescribePixelFormat(hDC,this->m_GLPixelIndex,sizeof(PIXELFORMATDESCRIPTOR),&pixelDesc)==0)
        {
            return FALSE;
        }
    }

    if(SetPixelFormat(hDC,this->m_GLPixelIndex,&pixelDesc)==FALSE)
    {
        return FALSE;
    }
    return TRUE;


4.MFC的显示用的是DC,而OpenGL的显示需要绘制环境(RC),故要将DC“用作”RC,具体过程是用DC创建RC然后将其设为当前RC。在View类中加入一个保护型的成员函数bool CreateViewGLContext(HDC hDC),并加入一个保护型的成员变量(即RC的句柄)HGLRC m_hGLContext,并在CreateViewGLContext函数中添加如下代码
   this->m_hGLContext = wglCreateContext(hDC);
    if(this->m_hGLContext==NULL)
    {//创建失败
        return FALSE;
    }
    if(wglMakeCurrent(hDC,this->m_hGLContext)==FALSE)
    {//选为当前RC失败
        return FALSE;
    }
    return TRUE;


5.在View类的OnCreate函数中调用前面那两个函数。在OnCreate函数中添加如下代码
    HWND hWnd = this->GetSafeHwnd();    
    HDC hDC = ::GetDC(hWnd);
    if(this->SetWindowPixelFormat(hDC)==FALSE)
    {
        return 0;
    }
    if(this->CreateViewGLContext(hDC)==FALSE)
    {
        return 0;
    }

在这代码之后可以自己加一些OpenGL的初始化代码

6.添加WM_DESTROY的消息处理函数Ondestroy( ),如下
void C??View::OnDestroy() 
{
    CView::OnDestroy();
    
    // TODO: Add your message handler code here
    if(wglGetCurrentContext()!=NULL)
    {
        wglMakeCurrent(NULL,NULL);
    }
    if(this->m_hGLContext!=NULL)
    {
        wglDeleteContext(this->m_hGLContext);
        this->m_hGLContext = NULL;
    }
}
不用OpenGL时得释放它的资源

7.在View类的构造函数中加入
    this->m_GLPixelIndex = 0;
    this->m_hGLContext = NULL;

至此已经构造好了框架,可以利用OpenGL进行画图了

8.为View类添加WMSIZE的消息处理函数OnSize,代码如下:
void C??View::OnSize(UINT nType, int cx, int cy) 
{
    CView::OnSize(nType, cx, cy);
    
    // TODO: Add your message handler code here
    GLsizei width,height;
    GLdouble aspect;
    width = cx;
    height = cy;
    if(cy==0)
    {
        aspect = (GLdouble)width;
    }
    else
    {
        aspect = (GLdouble)width/(GLdouble)height;
    }
    glViewport(0,0,width,height);
    glMatrixMode(GL_PROJECTION);
    glLoadIdentity();
    gluOrtho2D(0.0,500.0*aspect,0.0,500.0);
    glMatrixMode(GL_MODELVIEW);
    glLoadIdentity();
}

某些OpenGL的教程中说要在reshape之类的函数中加一些代码,就加到这里。目的是防止窗口大小改变时显示的东西变扁,另外可以设置显示范围及投影方式

9.为View类添加WM_PAINT的消息处理函数OnPaint,代码如下:
void C??View::OnPaint() 
{
    CPaintDC dc(this); // device context for painting
    
    // TODO: Add your message handler code here
    
    // Do not call CView::OnPaint() for painting messages

    glLoadIdentity();
    glClear(GL_COLOR_BUFFER_BIT);
    glBegin(GL_POLYGON);
        glColor4f(1.0f,0.0f,0.0f,1.0f);
        glVertex2f(100.0f,50.0f);
        glColor4f(0.0f,1.0f,0.0f,1.0f);
        glVertex2f(450.0f,400.0f);
        glColor4f(0.0f,0.0f,1.0f,1.0f);
        glVertex2f(450.0f,50.0f);
    glEnd();
    glFlush();
}
需要显示什么东东就在这里加了。这个程序的运行结果是黑色背景下彩色渐变的三角形。 

你可能感兴趣的:(windows,框架,user,null,mfc,buffer)