1. Win32控制檯方式
建立Win32 控制檯程序,在頭文件中加入
#include <windows.h>
#include <wingdi.h>
#include <GL/gl.h>
#include <GL/glu.h >
#include <GL/glaux.h>
2. MFC方式
(1)採用VC AppWizard嚮導創建空的MFC(EXE)工程框架,整個過程總共6步,值得指出的是一般情況下在嚮導的第1步選擇創建工程的模式都爲單文檔,以下的步驟中假設創建的工程名爲First.
(2)設置所創建工程的Link屬性。打開工程/設置/連接,在對象/庫模塊中加入opengl32.lib glu32.lib glaux.lib.
(3)在視圖類(View)的頭文件(Firstview.h)中加上:
#include <GL/gl.h>
#include <GL/glu.h>
#include <GL/glaux.h>
(4)在視圖類的實現文件Firstview.cpp中處理成員函數PreCreatWindow(),加上如下代碼:
cs.style |=WS_CLIPISBLINGS|WS_CLIPCHILDREN|CS_OWNDC;
用來設置OpenGL繪圖窗口的風格
(5)在視圖類的實現文件Firstview.cpp中處理成員函數OnCreate(),來創建OpenGL的繪 圖設備。OpenGL繪圖的機制是:先用OpenGL的繪圖上下文Rendering Context(簡稱爲 RC)把圖畫好,再把所繪結果通過SwapBuffers()函數傳給Window的繪圖上下文Device Context(簡稱爲DC)。要注意的是,程序運行過程中,可以有多個DC,但只能有一個 RC。因此當一個DC畫完圖後,要立即釋放RC,以便其他的DC也使用。在後面的代 碼中將有詳細解釋。
int CFirstView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
InitializeOpenGL();
return 0;
}
void CFirstView::InitializeOpenGL()
{
m_pDC=new CClientDC(this); // 創建OpenGL設備描述表
ASSERT(m_pDC!=NULL);
If(!SetupPixelFormat()) // 設置象素格式
return;
m_hRC=::wglCreateContext(m_pDC->m_hDC); // 創建OpenGL渲染描述表
::wglMakeCurrent(m_pDC->m_hDC,m_hRC); // 將RC與DC關聯起來
}
BOOL CFirstView::SetupPixelFormat()
{
static PIXELFORMATDESCRIPTOR pfd=
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW |
PFD_SUPPORT_OPENGL |
PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,
24,
0,0,0,0,0,0,
0,
0,
0,
0,0,0,0,
32,
0,
0,
PFD_MAIN_PLANE,
0,
0,0,0
};
int m_PixelFormat;
if({m_PixelFormat=ChoosePixelFormat(m_pDC->m_hDC,&pfd)==0)
{
MessageBox(“OpenGL的像素選擇格式失敗“);
return FALSE;
}
if(SetPixelFormat(m_pDC->m_hDC,m_PixelFormat,&pfd))==FALSE)
{
MessageBox(“OpenGL的像素格式的設置失敗“);
return FALSE;
}
return TRUE;
}
或
int CFirstView::OnCreate(LPCREATESTRUCT lpCreateStruct)
{
if (CView::OnCreate(lpCreateStruct) == -1)
return -1;
// TODO: Add your specialized creation code here
gl_Init();
return 0;
}
void CFirstView::gl_Init()
{
//下面的結構說明繪圖設備的像素格式
PIXELFORMATDESCRIPTOR pfd={
sizeof(PIXELFORMATDESCRIPTOR), //數據結構大小
1, //數據結構版本號
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL|PFD_DOUBLEBUFFER,
PFD_TYPE_RGBA,//緩衝區可以在窗口上繪圖,支持OpenGL繪圖
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, //忽略層,可見性和損毀掩膜
};//得到當前正在使用的繪圖設備句柄
m_hDC=GetDC()->GetSafeHdc();
//根據當前繪圖設備的特性,爲之選擇一個與pfd所指定的格式相匹配
//的像素格式,存於nPixelFormat中
int nPixelFormat=::ChoosePixelFormat(m_hDC,&pfd);
//將當前繪圖設備的像素格式設爲nPixelFormat
::SetPixelFormat(m_hDC,nPixelFormat,&pfd);
//根據當前繪圖設備,創建一個像素格式與之匹配的OpenGL的圖形操作設備表
m_hRC=::wglCreateContext(m_hDC);
/*指定OpenGL的圖形操作設備表是m_hRC,並且建立它與當前繪圖設備
m_hDC間的連接,下列函數執行後,所有繪圖命令的結果都出現在設
備m_hDC上*/
::wglMakeCurrent(m_hDC,m_hRC);
}
(6)在文件Firstview.cpp中處理OnDestroy(),在程序退出時處理該函數,以釋放在程序啓動時所申請的OpenGL變量(包括RC,DC等)。
void CFirstView::OnDestroy()
{
CView::OnDestroy();
// TODO: Add your message handler code here
::wglMakeCurrent(m_pDC->m_hDC,NULL); // 釋放與m_hDC 對應的 RC
::wglDeleteContext(m_hRC); // 刪除 RC
if(m_pDC)
delete m_pDC; // 刪除當前 View 擁有的 DC
}
(7)在文件Firstview.cpp中處理OnEraseBkgnd()
BOOL CFirstView::OnEraseBkgnd(CDC* pDC)
{
// TODO: Add your message handler code here and/or call default
//return CView::OnEraseBkgnd(pDC);
return TRUE;
}
(8)在文件Firstview.cpp中處理OnDraw ()
void CFirstView::OnDraw(CDC* pDC)
{
CVaseModelDoc* pDoc = GetDocument();
ASSERT_VALID(pDoc);
wglMakeCurrent(m_pDC->m_hDC,m_hRC); // 使RC與當前DC 相對應
myDrawScene(); //具體的繪圖函數,在RC中繪製
SwapBuffers(m_pDC->m_hDC);//把RC中所繪傳的到當前的DC上,從而在屏幕上顯示
wglMakeCurrent(m_pDC->m_hDC,NULL); // 釋放與m_hDC 對應的 RC
}
(9)在文件Firstview.cpp中處理RenderScene()
BOOL CFirstView::myDrawScene()//用來渲染的函數,說白了就是繪圖函數
{
glClearColor(0.0f, 0.0f, 0.0f,1.0f);
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
glBegin(GL_LINES);
glColor3f(1.0f,0.0f,0.0f);
glVertex3f(0.0f,0.0f,0.0f);
glVertex3f(1.0f,1.0f,0.0f);
glEnd();
glBegin(GL_LINES);
glColor3f(0.0f,1.0f,0.0f);
glVertex3f(0.0,0.0,0.0);
glVertex3f(1.0,-1.0,0.0);
glEnd();
glFlush ();
return TRUE;
}
(10)在文件Firstview.cpp中處理OnSize(),該函數響應窗口縮放事件,因此所顯示圖形可以跟隨窗口的縮放而等比縮放。
void CVaseModelView::OnSize(UINT nType, int cx, int cy)
{
CView::OnSize(nType, cx, cy);
// TODO: Add your message handler code here
glViewport(0,0,cx,cy);
glMatrixMode(GL_PROJECTION);
glLoadIdentity();
if(cx<=cy)
glOrtho(-1.50*cx/cy,1.50*cx/cy,-1.50,1.50,-10.0,10.0);
else
glOrtho(-1.50,1.50,-1.50*cy/cx,1.50*cy/cx,-10.0,10.0);
glMatrixMode(GL_MODELVIEW);
glLoadIdentity();
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);
myDrawScene();
}
注:定義 HDC m_hDC;或CDC* m_hDC;