本文是在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 FilesMicrosoft Visual StudioVC98Lib
如果一些lib文件没有,可以去网上搜下,自己下载。
3、在stdafx.h中添加OpenGL头文件
//OpenGL Headers #include <glgl.h> //OpenGL32库的头文件 #include <glglu.h> //GLu32库的头文件 #include <glglut.h> //OpenGL实用库的头文件 #include <glglaux.h> //GLaux库的头文件
以上的头文件需要存在于VC6.0安装好的目录下的Include下的GL文件夹下,例如:
C:Program FilesMicrosoft Visual StudioVC98IncludeGL
如果一些头文件没有,可以去网上搜下,自己下载。
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()
原文链接: