OPENGL是什么?
OPENGL是什么?
OpenGL三逗猛明維圖形標準是由AT&T公司UNIX軟件實驗室、IBM
、DEC、SUN、HP、Microsoft和SGI等多家公司在GL圖形庫標準的基礎
上聯合推出的開放式圖形庫,它使在微機上實現三維真實
感圖形的生成與顯示成為可能。由于OpenGL是開放的圖形標
準,用戶原先在UNIX下開發的OpenGL圖形軟件很容易移植到微
機上的WindowsNT/95上。筆者在VisualC++4.1(以下簡稱VC)集
成環境下,開發了基于OpenGL的三維真實感圖形應用程序,現
介紹如山告下。
微機上的OpenGL開發環境
基于OpenGL標準開發的應用程序必須運行于32位Windows
平臺下,如WindowsNT或Windows95環境;而且運行時還需有動態
鏈接庫OpenGL32.DLL、Glu32.DLL,這兩個文件在安裝WindowsNT時已
自動裝載到C:WINNTSYSTEM32目錄下(這里假定用戶將WindowsNT
安裝在C盤上);而對于使用Windows95平臺的用戶,則需手工將
兩個動態庫復制到Windows95目錄的SYSTEM子目錄中。安裝了
WindowsNT/95和VC4.1后,用戶就具備了基于OpenGL開發三維圖
形軟件的基本條件。
OpenGL程序設計的基本步驟
1.OpenGL在WindowsNT下的運行機制
OpenGL工作在客戶機/服務器模式下,當客戶方(即基
于OpenGL標準開發的應用程序)向服務器(OpenGL核心機制)發出
命令時,由服務器負責解釋這些命令。通常情況下,客戶方
和服務器是運行在同一臺微機上的。由于OpenGL的運行機制
是客戶機/服務器模式,這使得用戶能夠十分方便地在網
絡環境下使用OpenGL,OpenGL在WindowsNT上的這種實現方式通常
稱為網絡透明性。
OpenGL的圖形庫函數封裝在動態鏈接庫OpenGL32.DLL中,
客戶機中的所有OpenGL函數調用,都被傳送到服務器上,由
WinSrv.DLL實現功能,再將經過處理的指令發送到Win32設備驅
動接口(DDI),從而實現在計算機屏幕上產生圖像。
若使用OpenGL圖形加速卡,則上述機制中將添加兩個
驅動器:OpenGL可裝載客戶模塊(OpenGLICD)將安裝在客戶端;硬
件指定DDI將安裝在服務器端,與WinDDI同一級別。
2.OpenGL的庫函數
開發基于OpenGL的應用程序,必須先了解OpenGL的庫函
數。OpenGL函數命令方式十分有規律,每個庫函數均有前綴gl
、glu、aux,分別表示該函數屬于OpenGL基本庫、實用庫或輔助
庫。WindowsNT下的OpenGL包含了100多個核心函數,均以gl作為前
綴,同時還支持另外四類函數:
OpenGL實用庫函數:43個,以glu作為前綴;
OpenGL輔助庫函數:31個,以aux作為前綴;
Windows專用庫函數(WGL):6個,以wgl作為前綴;
Win32API函數(WGL):5個,無前綴。
OpenGL的115個核心函數提供了最基本的功能,可以實
現三維建模、建立光照模型、反走樣、紋理映射等;OpenGL實
用庫函數在核心函數的上一層,這類函數提供了簡單的調
用方法,其實質是調用核心函數,目的是減輕開發者的編程
工作量;OpenGL輔助庫函數是一些特殊的函數,可以供初學者
熟悉OpenGL的編程機知寬制,然而使用輔助庫函數的應用程序只
能在Win32環境中使用,可移植性較差,所以開發者應盡量避
免使用輔助庫函數;Windows專用庫函數(WGL)主要針對WindowsNT
/95環境的OpenGL函數調用;Win32API函數用于處理像素存儲格
式、雙緩存等函數調用。
3.VC環境下基于OpenGL的編程步驟
下面介紹在VC環境中建立基于Opeetting菜單選項,在Link欄的Lib輸入域中
添加openg132.lib、glu32.lib,若需使用OpenGL的輔助庫函數,則還
需添加glaux.lib。
(3)選擇View/ClassWizard菜單選項,打開MFC對話框,在
ClassName欄中選擇CMyTestView類,進行以下操作:
選擇WM_CREATE消息,鼠標單擊EditCode,將OpenGL初始化代碼
添加到OnCreate()函數中:
/*定義像素存儲格式*/
PIXELFORMATDESCRIPTORpfd=
{
sizeof(PIXELFORMATDESCRIPTOR),
1,
PFD_DRAW_TO_WINDOW|PFD_SUPPORT_OPENGL,
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,
}
CCLientdc(this);
intpixelFormat=ChoosePixelFormat(dc.m_hDC,&pfd);
BOOLsuccess=SetPixelFormat(dc.m_hDC,pixelFormat,&pfd);
m_hRC=wglCreateContext(dc.m_hDC);
選擇WM_DESTORY消息,在OnDestory()中添加以下代碼:
wglDeleteContext(m_hRC);
在MyTestView.cpp中,將以下代碼添加到PreCreateWindows()函數中:
cs.style|=WS_CLIPCHILDREN|WS_CLIPSIBLINGS;
OpenGL只對WS_CLIPCHILDREN|WS_CLIPSIBLINGS類型窗口有效;
在MyTestView.cpp中,將以下代碼添加到OnDraw()函數中:
wglMakeCurrent(pDC->m_hDC,m_hRC);
DrawScene();//用戶自定義函數,用于繪制三維場景;
wglMakeCurrent(pDC->m_hDC,NULL);
在MyTestView.cpp中,添加成員函數DrawScene():
voidCMyTestView::DrawScene()
{/*繪制三維場景*/}
(4)在MyTestView.h中包含以下頭文件并添加類成員說明:
#include
#include
#include
在CTestView類中的protected:段中添加成員變量聲明:
HGLRCm_hRC;
同時添加成員函數聲明:
DrawScene();
這樣,一個基于OpenGL標準的程序框架已經構造好,用
戶只需在DrawScene()函數中添加程序代碼即可。
建立三維實體模型
三維實體建模是整個圖形學的基礎,要生成高逼真
度的圖像,首先要生成高質量的三維實體模型。
OpenGL中提供了十幾個生成三維實體模型的輔助庫函
數,這些函數均以aux作為函數名的前綴。簡單的模型,如球
體、立方體、圓柱等可以使用這些輔助函數來實現,如
auxWireSphere(GLdoubleradius)(繪制一半徑為radius的網狀球體)。
但是這些函數難以滿足建立復雜三維實體的需要,所以用
戶可以通過其它建模工具(如3DS等)來輔助建立三維實體模
型數據庫。筆者在三維實體的建模過程中采用3DS提供的2D
Shape、3DLofter和3DEditor進行模型的編輯,最后通過將模型數
據以DXF文件格式輸出存儲供應用程序使用。
真實感圖形的繪制
1.定義光照模型和材質
(1)光源。OpenGL提供了一系列建立光照模型的庫函
數,使用戶可以十分方便地在三維場景中建立所需的光照
模型。OpenGL中的光照模型由環境光(AmbientLight)、漫射光
(DiffuseLight)、鏡面反射光(SpecularLight)等組成,同時還可設
置光線衰減因子來模擬真實的光源效果。
例如,定義一個黃色光源如下:
GlfloatLight_position[]={1.0,1.0,1.0,0.0,};
GlfloatLight_diffuse[]={1.0,1.0,0.0,1.0,};
glLightfv(GL_LIGHT0,GL_POSTTION,light_position);//定義光源位置
glLightfv(GL_LIGHT0,GL_DIFFUSE,light_diffuse);//定義光源漫射光
光源必須經過啟動后才會影響三維場景中的實體,可以通過以下指令使光源有效:<
glEnable(LIGHTING);//啟動光照模型;
glEnable(GL_LIGHT0);//使光源GL_LIGHT0有效;
OpenGL中一共可以定義GL_LIGHT0~GL_LIGHT7八個光源。
(2)材質。OpenGL中的材質是指構成三維實體的材料在
光照模型中對于紅、綠、藍三原色的反射率。與光源的定義
類似,材質的定義分為環境、漫射、鏡面反射成分,另外還
有鏡面高光指數、輻射成分等。通過對三維實體的材質定義
可以大大提高應用程序所繪制的三維場景的逼真程度。例
如:
/*設置材質的反射成分*/
GLfloatmat_ambient[]={0.8,0.8,0.8,1.0};
GLfloatmat_diffuse[]={0.8,0.0,0.8,1.0};/*紫色*/
GLfloatmat_specular[]={1.0,0.0,1.0,1.0};/*鏡面高光亮紫色*/
GLfloatmat_shiness[]={100.0};/*高光指數*/
glMaterialfv(GL_FRONT,GL_AMBIENT,mat_ambient);/*定義環境光反射率*/
glMaterialfv(GL_FRONT,GL_DIFFUSE,mat_diffuse);/*定義漫射光反射率*/
glMaterialfv(GL_FRONT,GL_SPECULAR,mat_specular);/*定義鏡面光反射率*/
glMaterialfv(GL_FRONT,GL_SHINESS,mat_shiness);/*定義高光指數*/
(3)材質RGB值與光源RGB值的關系。OpenGL中材質的顏色
與光照模型中光源的顏色含義略有不同。對于光源,R、G、B
值表示三原色在光源中所占有的比率;而對于材質定義,R、
G、B的值表示具有這種材質屬性的物體對于三原色的反射
比率,場景中物體所呈現的顏色與光照模型、材質定義都相
關。例如,若定義的光源顏色是(Lr,Lg,Lb)=(1.0,1.0,1.0)(白光),
物體的材質顏色定義為(Mr,Mg,Mb)=(0.0,0.0,0.8),則最終到達人
眼的物體顏色應當是(Lr*Mr,Lg*Mg,Lb*Mb)=(0.0,0.0,0.8)(藍色)。
2.讀取三維模型數據
為了繪制三維實體,我們首先必須將預先生成的三
維實體模型從三維實體模型庫中讀出。下圖描述了讀取三
維實體模型的流程。
3.三維實體繪制
由于3DS的DXF文件中對于三維實體的描述是采用三角
形面片逼近的方法,而在OpenGL函數庫中,提供了繪制三角形
面片的方法,所以為三維實體的繪制提供了方便。以下提供
了繪制三角形面片的方法:
glBegin(TRANGLES);//定義三角形繪制開始
glVertexf((GLfloat)x1,(GLfloat)y1,(GLfloat)z1);//第一個頂點
glVertexf((GLfloat)x2,(GLfloat)y2,(GLfloat)z2);//第二個頂點
glVertexf((GLfloat)x3,(GLfloat)y3,(GLfloat)z3);//第三個頂點
glEnd();//繪制結束
為了提高三維實時動畫的顯示速度,我們利用了
OpenGL庫中的顯示列表(DisplayList)的功能,將三維場景中的實
體分別定義為單獨的顯示列表,預先生成三維實體。在圖形
顯示時,只需調用所需的顯示列表即可顯示相應的三維實
體,而不需要重新計算實體在場景中的坐標,避免了大量的
浮點運算。在調用顯示列表前所作的旋轉、平移、光照、材
質的設定都將影響顯示列表中的三維實體的顯示效果。具
體實現算法如下:
for(ObjectNo=0;ObjectNo<實體個數;ObjectNo++)
{
glNewList(ObjectNo,GL_COMPILE);//創建第ObjectNo個實體的顯示列表
for(Fac