基于OpenGL顯示平台功能開發-MFC架構篇
簡介
關于OpenGL MFC應用程式架構的搭建,大家可以在網上找到很多相關的曆程。而且按照曆程的步驟,基本上可以很順利地搭建出來。為了更能充分的幫助讀者了解MFC下OpenGL環境搭建的過程。本篇主要對其步驟進行了一個詳細的介紹,在下一篇文章中會對其在建立中涉及到的理論知識及相應的OpenGL API函數接口做一個具體的分析介紹。
環境搭建步驟(單文檔)
- 選擇一個編譯環境(如VC2010),安裝GLUT工具包
- 下載下傳glut庫,下載下傳位址http://openglsource.com/download/download.htm,下載下傳glut-3.7.6-bin.zip
-
解壓下載下傳包,得到5個檔案(glut.dll,glut.h,glut.lib,glut32.dll,glut32.lib)
1)把glut.h複制到D:\Program Files\Microsoft\Visual Studio10.0\VC\include\gl檔案夾中,如果沒有gl這個檔案夾則可以自己建立一個。(D是你安裝VS的盤的目錄)
2)把glut.lib和glut32.lib放到靜态函數庫所在檔案夾(即與include并排的lib檔案夾下)。
3)把解壓得到的glut.dll和glut32.dll放到作業系統目錄下面的system32檔案夾内。(典型的位置為:C:\Windows\System32)
- OpenGL在VC2010 下的配置
- 建立MFC單文檔應用程式,名稱命名為MyOpenGLProject,應用程式類型選擇單個文檔,其他預設,一直下一步,點選完成。
- 右擊工程名->屬性,彈出屬性頁,點選連結器->附加依賴項,添加glut.lib;glut32.lib,中間以分号隔開
- 在stdafx.h中添加#include< gl/glut.h>,此時opengl相關的檔案配置已基本完成。
- 接着在MyOpenGLProjectView.h頭檔案中添加如下成員及消息函數:
class CMyOpenGLProjectView : public CView { ... public: virtual void OnDraw(CDC* pDC); public: afx_msg int OnCreate(LPCREATESTRUCT lpCreateStruct); afx_msg void OnSize(UINT nType, int cx, int cy); afx_msg BOOL OnEraseBkgnd(CDC* pDC); afx_msg void OnDestroy(); protected: void Init(); BOOL InitializeOpenGL(CDC* pDC); void SetLogicalPalette(); BOOL SetupPixelFormat(); void RunScene(); // 繪圖工作再此完成 void Projection(); // 實施投影變換 private: HGLRC m_hRC; // OpenGL繪制描述表 HPALETTE m_hPalette; // OpenGL調色闆 CDC* m_pDC; // OpenGL裝置描述表 GLfloat m_width; // 螢幕長度 GLfloat m_height; // 螢幕寬度 GLfloat m_fViewAngle; // 視角,初始45 GLfloat camPos[]; ... }
- 在MyOpenGLProject.cpp源檔案中添加如下實作:
CMyOpenGLProjectView::CMyOpenGLProjectView()
{
m_hRC = NULL;
m_hPalette = NULL;
m_pDC = NULL;
}
void CMyOpenGLProjectView::OnDraw(CDC* /*pDC*/)
{
CMyOpenGLProjectDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
if (!pDoc)
return;
RunScene();
}
int CMyOpenGLProjectView ::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -)
return -;
m_pDC = new CClientDC(this);
InitializeOpenGL(m_pDC);
Init();
return ;
}
BOOL CMyOpenGLProjectView ::OnEraseBkgnd(CDC* pDC)
{
return TRUE;
}
void CMyOpenGLProjectView ::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
m_width = cx;
m_height = cy;
glViewport(,,cx,cy);
}
void CMyOpenGLProjectView ::OnDestroy()
{
CView::OnDestroy();
wglMakeCurrent(,);
wglDeleteContext( m_hRC);
if (m_hPalette)
DeleteObject(m_hPalette);
if ( m_pDC )
{
delete m_pDC;
}
}
void CMyOpenGLProjectView ::Init()
{
camPos[] = f;
camPos[] = f;
camPos[] = f;
m_fViewAngle = f; // 初始化相機視角45°
glClearColor(,,,); //單一背景顔色預設值
glClearDepth(F);
glShadeModel(GL_SMOOTH);
glEnable(GL_DEPTH_TEST);
}
BOOL CMyOpenGLProjectView ::InitializeOpenGL(CDC *pDC)
{
m_pDC = pDC;
SetupPixelFormat();
//生成繪制描述表
m_hRC = wglCreateContext(m_pDC->GetSafeHdc());
//重置目前繪制描述表
wglMakeCurrent(m_pDC->GetSafeHdc(), m_hRC);
return TRUE;
}
BOOL CMyOpenGLProjectView ::SetupPixelFormat()
{
PIXELFORMATDESCRIPTOR pfd = {
sizeof(PIXELFORMATDESCRIPTOR), // pfd結構的大小
, // 版本号
PFD_DRAW_TO_WINDOW | // 支援在視窗中繪圖
PFD_SUPPORT_OPENGL | // 支援 OpenGL
PFD_DOUBLEBUFFER, // 雙緩存模式
PFD_TYPE_RGBA, // RGBA 顔色模式
, // 24 位顔色深度
, , , , , , // 忽略顔色位
, // 沒有非透明度緩存
, // 忽略移位位
, // 無累加緩存
, , , , // 忽略累加位
, // 32 位深度緩存
, // 無模闆緩存
, // 無輔助緩存
PFD_MAIN_PLANE, // 主層
, // 保留
, , // 忽略層,可見性和損毀掩模
};
int pixelformat;
pixelformat = ChoosePixelFormat(m_pDC->GetSafeHdc(), &pfd);//選擇像素格式
SetPixelFormat(m_pDC->GetSafeHdc(), pixelformat, &pfd); //設定像素格式
if(pfd.dwFlags & PFD_NEED_PALETTE)
SetLogicalPalette(); //設定邏輯調色闆
return TRUE;
}
void CMyOpenGLProjectView ::SetLogicalPalette()
{
struct
{
WORD Version;
WORD NumberOfEntries;
PALETTEENTRY aEntries[];
} logicalPalette = { , };
BYTE reds[] = {, , , , , , , };
BYTE greens[] = {, , , , , , , };
BYTE blues[] = {, , , };
for (int colorNum=; colorNum<; ++colorNum)
{
logicalPalette.aEntries[colorNum].peRed =
reds[colorNum & ];
logicalPalette.aEntries[colorNum].peGreen =
greens[(colorNum >> ) & ];
logicalPalette.aEntries[colorNum].peBlue =
blues[(colorNum >> ) & ];
logicalPalette.aEntries[colorNum].peFlags = ;
}
m_hPalette = CreatePalette ((LOGPALETTE*)&logicalPalette);
}
void CMyOpenGLProjectView::Projection()
{
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
gluPerspective(m_fViewAngle, m_width/m_height, F, F);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
gluLookAt(camPos[],camPos[],camPos[],,,,,,);
}
void CMyOpenGLProjectView::RunScene()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Projection(); // 實施投影變換,透視投影
SwapBuffers(m_pDC->GetSafeHdc());
}
`
3. 至此,一個簡單的MFC下OpenGL繪圖環境基本已搭建完成,運作程式,效果如下所示。

繪制旋轉的三角形
為了使場景的顯示看的豐富,下面就在場景中繪制一個簡單的帶顔色的三角形,并使三角形能繞着軸旋轉。
繪制三角形的代碼如下:
void CMyOpenGLProjectView::RunScene()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Projection(); // 實施投影變換,透視投影
// 繪制場景
glPushMatrix();
glBegin( GL_TRIANGLES );
glColor3f( , , );
glVertex3f( , , );
glColor3f( , , );
glVertex3f( -, -, );
glColor3f( , , );
glVertex3f( , -, );
glEnd();
glPopMatrix();
SwapBuffers(m_pDC->GetSafeHdc());
}
運作程式,效果如下所示。
添加旋轉操作
1. 首先,在MyOpenGLProjectView.h檔案中添加如下成員
class CMyOpenGLProjectView : public CView
{
…
public:
afx_msg void OnTimer(UINT_PTR nIDEvent);
private:
static double m_Rotatf; // 模型旋轉角度變量
…
}
2. 在MyOpenGLProjectView.cpp檔案中實作
double CMyOpenGLProjectView::m_Rotatf = 0.0; // 對旋轉變量進行初始化指派
void CMyOpenGLProjectView::RunScene()
{
glClear( GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT );
Projection(); // 實施投影變換,透視投影
// 繪制場景
glPushMatrix();
glRotatef(m_Rotatf,0,1,0); // 添加,繞y軸旋轉
glBegin( GL_TRIANGLES );
glColor3f( 1.0, 0.0, 0.0 );
glVertex3f( 0.0, 300.0, 0.0 );
glColor3f( 0.0, 1.0, 0.0 );
glVertex3f( -300.0, -300.0, 0.0 );
glColor3f( 0.0, 0.0, 1.0 );
glVertex3f( 300.0, -300.0, 0.0 );
glEnd();
glPopMatrix();
SwapBuffers(m_pDC->GetSafeHdc());
}
void CMyOpenGLProjectView::OnTimer(UINT_PTR nIDEvent)
{
m_Rotatf += 10.0; // 添加
RunScene();
CView::OnTimer(nIDEvent);
}
int CMyOpenGLProjectView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
m_pDC = new CClientDC(this);
InitializeOpenGL(m_pDC);
Init();
SetTimer(0,100,0); // 添加
return 0;
}
至此,旋轉動畫已添加完成,運作效果如下所示:
源代碼位址連結:OpenGL MFC模型旋轉