MFC基于对话框的用Picture Control显示OpenGL

一、总体思路

  1. 在MFC对话框上搭建OpenGL渲染环境的流程图

这里写图片描述

2.图形操作描述

在Windows下窗口程序必须首先处理设备描述表(Device Contexts,DC),DC包括许多如何在窗口上显示图形的信息,既指定画笔和刷子的颜色,设置绘图模式、调色板、映射模式以及其它图形属性。同样,OpenGL for Windows95的程序也必须使用DC,这与其它Windows 95程序类似。但是,OpenGL for Windows 必须处理特殊的DC图形操作描述表,这是DC中专为OpenGL使用的一种。一个OpenGL应用图形操作描述表内有OpenGL与Windows 95窗口系统相关的各种信息。一个OpenGL应用首先必须创建一个图形操作描述表,然后再启动它,最后在所定义的窗口内按常规方式调用OpenGL函数绘制图形。

一个图形操作描述表不同于其它DC,它们调用每个GDI函数都需要一个句柄,而图形操作描述表方式下只需一个句柄就可以任意调用OpenGL函数。也就是说,只要当前启用了某个图形操作描述表,那么在未删除图形操作描述表之前可以调用任何OpenGL函数,进行各种操作。
(此二段引用http://blog.csdn.net/jiangdf/article/details/8464849

3.像素格式

在创建一个图形操作表之前,首先必须设置像素格式。像素格式含有设备绘图界面的属性,这些属性包括绘图界面是用RGBA模式还是颜色表模式,像素缓存是用单缓存还是双缓存,以及颜色位数、深度缓存和模板缓存所用的位数,还有其它一些属性信息。
(此段引用http://blog.csdn.net/jiangdf/article/details/8464849

二、具体过程

在VS2013下编程

  1. 创建基于对话框的MFC项目

    选择基于对话框类型

  2. 导入OpenGL头文件和Lib文件

    2.1 在stdafx.h中添加语句(头文件)

#include <gl/gl.h>
#include <gl/glu.h>
#include <gl/glut.h>
#include <gl/glaux.h>

2.2在项目中添加OpenGL的lib库文件,右键项目||Properties,如下图,之后左边以此展开Configuration Properties || Linker || Input || Additional Dependencies || ,之后弹出的窗口中输入:opengl32.lib,glu32.lib,glaux.lib,三个库文件名,当然每个文件名之间应该是换行,不是逗号。

这里写图片描述
这里写图片描述
这里写图片描述
(此项引用http://blog.csdn.net/bbppbb/article/details/24314099

3.添删资源控件、成员函数、成员变量

3.1 在资源视图中的Dialog添加Picture Control,默认ID为IDC_STATIC。
删除“确定”和”删除”按钮。

3.2右击项目,选中类向导,出现对话框后选择COpenGLDlgDlg类。在选项卡中选择成员变量,如图添加成员变量。

变量说明:
m_hGLRC:用作创建RC后的句柄(地址)

m_GLPixelIndex:作为像素格式选择后的索引

hDC:设备描述表的句柄(地址)
这里写图片描述

3.3右击项目,选中类向导,出现对话框后选择COpenGLDlgDlg类。在选项卡中选择方法,如图添加成员函数。

函数说明:
void DrawOpenGL (void) :用于绘制图形

void Reshape (void) : 用于处理当Picture Control框改变时OpenGL的视图中的图形不变形。

bool SetWindowPixelFormat (HDC hDC):定义(设置)并为DC选择最佳像素格式

bool CreateViewGLRC (HDC hDC):创建渲染描述表RC(Render Context)并设置为当前RC

这里写图片描述
3.4添加相应函数功能代码

3.4.1
在OpenGLDlgDlg.cpp中的BOOL COpenGLDlgDlg::OnInitDialog()函数中添加如下代码,用于获取Picture Control的句柄(标识应用程序中的不同对象和同类中的不同的实例,也可以理解为一个智能指针)。

CWnd *pWnd = GetDlgItem(IDC_STATIC);
hDC = ::GetDC(pWnd->GetSafeHwnd());
if (SetWindowPixelFormat(hDC) == FALSE)
    return 0;
if (CreateViewGLRC(hDC) == FALSE)
    return 0;

这里写图片描述

3.4.2将bool COpenGLDlgDlg::SetWindowPixelFormat(HDC hDC)改写为以下代码。
bool COpenGLDlgDlg::SetWindowPixelFormat(HDC hDC)
{
static PIXELFORMATDESCRIPTOR pixelDesc;
pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixelDesc.nVersion = 1;
pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_STEREO_DONTCARE;
pixelDesc.iPixelType = PFD_TYPE_RGBA;
pixelDesc.cColorBits = 32;
pixelDesc.cRedBits = 8;
pixelDesc.cRedShift = 16;
pixelDesc.cGreenBits = 8;
pixelDesc.cGreenShift = 8;
pixelDesc.cBlueBits = 8;
pixelDesc.cBlueShift = 0;
pixelDesc.cAlphaBits = 0;
pixelDesc.cAlphaShift = 0;
pixelDesc.cAccumBits = 64;
pixelDesc.cAccumRedBits = 16;
pixelDesc.cAccumGreenBits = 16;
pixelDesc.cAccumBlueBits = 16;
pixelDesc.cAccumAlphaBits = 0;
pixelDesc.cDepthBits = 32;
pixelDesc.cStencilBits = 8;
pixelDesc.cAuxBuffers = 0;
pixelDesc.iLayerType = PFD_MAIN_PLANE;
pixelDesc.bReserved = 0;
pixelDesc.dwLayerMask = 0;
pixelDesc.dwVisibleMask = 0;
pixelDesc.dwDamageMask = 0;
m_GLPixelIndex = ChoosePixelFormat(hDC, &pixelDesc);
if (m_GLPixelIndex == 0)
{
m_GLPixelIndex = 1;
if (DescribePixelFormat(hDC, m_GLPixelIndex, sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc) == 0)
{
return FALSE;
}
}
if (SetPixelFormat(hDC, m_GLPixelIndex, &pixelDesc) == FALSE)
{
return FALSE;
}
return TRUE;
}

3.4.3在void COpenGLDlgDlg::OnPaint() 函数中 添加

    //设置视角,并使得都窗口改变时图形不变
    Reshape();
    //调用画图功能
    DrawOpenGL();

如图所示
这里写图片描述

3.4.4在BOOL COpenGLDlgTestDlg::CreateViewGLContext(HDC hDC)中加入如下代码,用于将设备描述表DC和OpenGL的RC(即渲染描述表)联系起来。

BOOL COpenGLDlgTestDlg::CreateViewGLContext(HDC hDC)
{
m_hGLRC=wglCreateContext(hDC);
if(m_hGLRC==NULL)
return FALSE;
if(wglMakeCurrent(hDC,m_hGLRC)==FALSE)
return FALSE;
return TRUE;
}

3.4.5 最后,在DrawOpenGL()中,添加我们需要绘制图形的代码。这里提供一段简单代码仅供测试。

void COpenGLDlgDlg::DrawOpenGL()
{

    glClear(GL_COLOR_BUFFER_BIT);// 将缓存清除为预先的设置值,即黑色
    //glTranslatef(0.8, 0.0, 0.0);//平移函数,暂时可以不用
    glBegin(GL_TRIANGLES);//开始画三角形
    glColor3f(1.0, 0.0, 0.0);//设置第一个顶点为红色
    glVertex2f(-2.0, -2.0);//设置第一个顶点的坐标
    glColor3f(0.0, 1.0, 0.0);//设置第二个顶点为绿色
    glVertex2f(2.0, -2.0);//设置第二个顶点的坐标
    glColor3f(0.0, 0.0, 1.0);//设置第三个顶点为蓝色
    glVertex2f(-0, 2.0);//设置第三个顶点的坐标
    glEnd();//三角形结束

    SwapBuffers(hDC);//切换缓冲区到客户区窗口
}

注意,SwapBuffers的参数为hDC,即指定缓冲区的切换窗口。

这里写图片描述

Ctrl+F5,得到图示图形即代表运行成功。

三、鸣谢

鸡啄米MFC系列教程

XjtrX http://blog.csdn.net/bbppbb/article/details/24314099

jiangdf http://blog.csdn.net/jiangdf/article/details/8464849

四、示例源码下载链接

http://download.csdn.net/detail/linyijiong/9711727

猜你喜欢

转载自blog.csdn.net/linyijiong/article/details/53647250