本文是在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 Files\Microsoft Visual Studio\VC98\Lib
如果一些lib文件沒有,可以去網上搜下,自己下載。
3、在stdafx.h中添加OpenGL頭文件
//OpenGL Headers
#include <gl\gl.h> //OpenGL32庫的頭文件
#include <gl\glu.h> //GLu32庫的頭文件
#include <gl\glut.h> //OpenGL實用庫的頭文件
#include <gl\glaux.h> //GLaux庫的頭文件
以上的頭文件需要存在於VC6.0安裝好的目錄下的Include下的GL文件夾下,例如:
C:\Program Files\Microsoft Visual Studio\VC98\Include\GL
如果一些頭文件沒有,可以去網上搜下,自己下載。
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()