转载自:http://blog.sina.com.cn/s/blog_8e6bfecf0100uuwy.html,觉得这个写的详细一些,自己测试也成功,在此基础上做了点修改,收藏记录分享下。。。
新建一个MFC的dialog工程(eg,C++MFC工程openGlMFC)。
为了方便进行字符串CString与其它格式的转换,在工程属性的Configuration Properties -> General -> Character Set中,不使用默认的Use Unicode Character Set,改为Use Multi-Byte Character Set。
在项目属性的linker->input->additional dependencies中加入:opengl32.lib;glu32.lib;glut32.lib;glaux.lib
在MFC组件中添加一个Picture Control组件,将组件ID改为IDC_RENDER
在stdafx.h的末尾加入:("#include< afxcontrolbars.h>"之后加入)
#include< GL/glut.h>
#include< GL/glaux.h>
在??Dlg.h的 "enum { IDD = IDD_??_DIALOG };" 下加入:
BOOL SetWindowPixelFormat(HDC hDC); // 设定像素格式
BOOL CreateViewGLContext(HDC hDC); // view GL Context
void RenderScene(); // 绘制场景
HDC hrenderDC; // DC
HGLRC hrenderRC; // RC
int PixelFormat; // 像素格式
在??Dlg.h的"DECLARE_MESSAGE_MAP()"下加入:
afx_msg void OnTimer(UINT nIDEvent); // 重载OnTimer函数
在??Dlg.cpp的"BEGIN_MESSAGE_MAP(CCOpenGLDlg, CDialog)...END_MESSAGE_MAP()"中加入:(注意不要加错了地方)
ON_WM_TIMER()
在??Dlg.cpp的OnInitDialog()中加入OpenGL的初始化声明etc:
CWnd* wnd = GetDlgItem(IDC_RENDER); // 初始化MFC中的OpenGL设置
hrenderDC = ::GetDC(wnd->m_hWnd);
if(SetWindowPixelFormat(hrenderDC) == FALSE) { // 设置hDC的像素格式
return 0;
}
if(CreateViewGLContext(hrenderDC) == FALSE) { // 由hDC转换得到hRC
return 0;
}
// openGL的初始化设置
glClearColor(0.0, 0.0, 0.0, 0.0);
glShadeModel(GL_SMOOTH);
//glViewport(0, 0, 200, 200);
glMatrixMode(GL_PROJECTION);
gluPerspective(45, 1, 0.1, 100.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
// 设置计时器,10ms刷新一次
SetTimer(1, 10, 0);
SetWindowPixelFormat()(设置像素格式的函数):
BOOL CCOpenGLDlg::SetWindowPixelFormat(HDC hDC) {// CCOpenGLDlg改为你自己创建的MFC类名
第一种写法:
/* PIXELFORMATDESCRIPTOR pixelDesc;
pixelDesc.nSize = sizeof(PIXELFORMATDESCRIPTOR);
pixelDesc.nVersion = 1;
pixelDesc.dwFlags = PFD_DRAW_TO_WINDOW | PFD_SUPPORT_OPENGL | PFD_DOUBLEBUFFER | PFD_TYPE_RGBA;
pixelDesc.iPixelType = PFD_TYPE_RGBA;
pixelDesc.cColorBits = 32;
pixelDesc.cRedBits = 0;
pixelDesc.cRedShift = 0;
pixelDesc.cGreenBits = 0;
pixelDesc.cGreenShift = 0;
pixelDesc.cBlueBits = 0;
pixelDesc.cBlueShift = 0;
pixelDesc.cAlphaBits = 0;
pixelDesc.cAlphaShift = 0;
pixelDesc.cAccumBits = 0;
pixelDesc.cAccumRedBits = 0;
pixelDesc.cAccumGreenBits = 0;
pixelDesc.cAccumBlueBits = 0;
pixelDesc.cAccumAlphaBits = 0;
pixelDesc.cDepthBits = 0;
pixelDesc.cStencilBits = 1;
pixelDesc.cAuxBuffers = 0;
pixelDesc.iLayerType = PFD_MAIN_PLANE;
pixelDesc.bReserved = 0;
pixelDesc.dwLayerMask = 0;
pixelDesc.dwVisibleMask = 0;
pixelDesc.dwDamageMask = 0;
PixelFormat = ChoosePixelFormat(hDC, &pixelDesc);
if(PixelFormat == 0) {
PixelFormat = 1;
if(DescribePixelFormat(hDC, PixelFormat, sizeof(PIXELFORMATDESCRIPTOR), &pixelDesc) == 0) {
return FALSE;
}
}
if(SetPixelFormat(hDC, PixelFormat,& pixelDesc) == FALSE) {
return FALSE;
}
return TRUE;*/
第二种写法:
/*
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR) , // pfd结构的大小
1, // 版本号
PFD_DRAW_TO_WINDOW | // 支持在窗口中绘图
PFD_SUPPORT_OPENGL | // 支持 OpenGL
PFD_DOUBLEBUFFER, // 双缓存模式
PFD_TYPE_RGBA, // RGBA 颜色模式
24, // 24 位颜色深度
0, 0, 0, 0, 0, 0, // 忽略颜色位
0, // 没有非透明度缓存
0, // 忽略移位位
0, // 无累计缓存
0, 0, 0, 0, // 忽略累计位
32, // 32 位深度缓存
0, // 无模板缓存
0, // 无辅助缓存
PFD_MAIN_PLANE, // 主层
0, // 保留
0, 0, 0 // 忽略层,可见性和损毁掩模
};
int iPixelFormat;
// 为设备描述表得到最匹配的像素格式
if ((iPixelFormat = ChoosePixelFormat(hdc, &pfd)) == 0)
{
MessageBox(_T("ChoosePixelFormat Failed"), NULL, MB_OK);
return 0;
}
// 设置最匹配的像素格式为当前的像素格式
if (SetPixelFormat(hdc, iPixelFormat, &pfd) == FALSE)
{
MessageBox(_T("SetPixelFormat Failed"), NULL, MB_OK);
return 0;
}
return 1;
*/
}
CreateViewGLContext()(由HDC转化得到HRC的函数):
BOOL CCOpenGLDlg::CreateViewGLContext(HDC hDC) {
hrenderRC = wglCreateContext(hDC);
if(hrenderRC == NULL) {
return FALSE;
}
if(wglMakeCurrent(hDC, hrenderRC) == FALSE) {
return FALSE;
}
return TRUE;
}
实现OpenGL绘图的RenderScene函数:
void CCOpenGLDlg::RenderScene() {
glClear(GL_COLOR_BUFFER_BIT);
glColor3f(1.0, 1.0, 1.0);
glLoadIdentity();
glTranslatef(0.0, 0.0, -5.0);
glBegin(GL_TRIANGLES);
glVertex3f(0.0, 1.0, 0.0);
glVertex3f(-1.0, -1.0, 0.0);
glVertex3f(1.0, -1.0, 0.0);
glEnd();
SwapBuffers(hrenderDC); // 使用glFlush()没有显示?
}
实现实时绘制场景的OnTimer函数是:
void CCOpenGLDlg::OnTimer(UINT nIDEvent) {
RenderScene();
CDialog::OnTimer(nIDEvent);
}
附上效果图: