第一課中,我教您如何創建一個
OpenGL窗口。這一課中,我將教您如何創建三角形和四邊形。我們講使用來創建GL_TRIANGLES一個三角形,GL_QUADS來創建一個四邊形。
在第一課代碼的基礎上,我們只需在DrawGLScene()過程中增加代碼。下面我重寫整個過程。如果您計劃修改上節課的代碼,只需用下面的代碼覆蓋原來的DrawGLScene()就可以了。
int DrawGLScene(GLvoid) // 此過程中包括所有的繪制代碼
{
glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);// 清除屏幕及深度緩存
glLoadIdentity(); // 重置視口
當您調用glLoadIdentity()之后,您實際上講當前點移到了屏幕中心,X坐標軸從左至右,Y坐標軸從下至上,Z坐標軸從里至外。OpenGL屏幕中心的坐標值是X和Y軸上的0.0f點。中心左面的坐標值是負值,右面是正值。移向屏幕頂端是正值,移向屏幕底端是負值。移入屏幕深處是負值,移出屏幕則是正值。
glTranslatef(x, y, z)沿著X,Y和Z軸移動。根據前面的次序,下面的代碼沿著X軸左移1.5個單位,Y軸不動(0.0f),最后移入屏幕6.0f個單位。注意在glTranslatef(x, y, z)中當您移動的時候,您并不是相對屏幕中心移動,而是相對與當前所在的屏幕位置。
glTranslatef(-1.5f,0.0f,-6.0f); // 左移1.5單位,并移入屏幕6.0 現在我們已經移到了屏幕的左半部分,并且將視圖推入屏幕背后足夠的距離以便我們可以看見全部的場景-創建三角形。glBegin(GL_TRIANGLES)的意思是開始繪制三角形,glEnd()告訴OpenGL三角形已經創建好了。通常您會需要畫3個頂點,可以使用GL_TRIANGLES。在絕大多數的顯卡上,繪制三角形是相當快速的。如果要畫四個頂點,使用GL_QUADS的話會更方便。但據我所知,絕大多數的顯卡都使用三角形來為對象著色。最后,如果您想要畫更多的頂點時,可以使用GL_POLYGON。
本節的簡單示例中,我們只畫一個三角形。如果要畫第二個三角形的話,可以在這三點之后,再加三行代碼(3點)。所有六點代碼都應包含在glBegin(GL_TRIANGLES)和glEnd()之間。在他們之間再不會有多余的點出現,也就是說,glBegin(GL_TRIANGLES)和glEnd()之間的點都是以三點為一個集合的。這同樣適用于四邊形。如果您知道實在繪制四邊形的話,您必須在第一個四點之后,再加上四點為一個集合的點組。另一方面,多邊形可以由任意個頂點,glBegin(GL_POLYGON)不在乎glBegin(GL_TRIANGLES)和glEnd()之間有多少行代碼。glBegin之后的第一行設置了多邊形的第一個頂點,glVertex的第一個參數是X坐標,然后依次是Y坐標和Z坐標。第一個點是上頂點,然后是左下頂點和右下頂點。glEnd()告訴OpenGL沒有其他點了。這樣將顯示一個填充的三角形。
譯者:
這里要注意的是存在兩種不同的坐標變換方式,glTranslatef(x,y,z)中的x,y,z是相對與您當前所在點的位移,但glVertex(x,y,z)是相對于glTranslatef(x,y,z)移動后的新原點的位移。因而這里可以認為glTranslate移動的是坐標原點,glVertex中的點是相對最新的坐標原點的坐標值。 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(); // 三角形繪制結束
在屏幕的左半部分畫完三角形后,我們要移到右半部分來畫正方形。為此要再次使用glTranslate。這次右移,所以X坐標值為正值。因為前面左移了1.5個單位,這次要先向右移回屏幕中心(1.5個單位),再向右移動1.5個單位。總共要向右移3.0個單位。
glTranslatef(3.0f,0.0f,0.0f); // 右移3單位 現在使用GL_QUADS繪制正方形。與繪制三角形的代碼相類似,畫四邊形也很簡單。唯一的區別是用GL_QUADS來替換了GL_TRIANGLES。并增加了一個點。我們使用順時針次序來畫正方形-左上-右上-右下-左下。采用順時針繪制的是對象的后表面。這就是說我們所看見的是正方形的背面。逆時針畫出來的正方形才是正面朝著我們的。現在這對您來說并不重要,但以后您必須知道。
glBegin(GL_QUADS); // 繪制正方形
glVertex3f(-1.0f, 1.0f, 0.0f); // 左上
glVertex3f( 1.0f, 1.0f, 0.0f); // 右上
glVertex3f( 1.0f,-1.0f, 0.0f); // 左下
glVertex3f(-1.0f,-1.0f, 0.0f); // 右下
glEnd(); // 正方形繪制結束
return TRUE; // 繼續運行
} 最后換掉窗口模式下的標題內容。
if (keys[VK_F1]) // F1鍵按下了么?
{
keys[VK_F1]=FALSE; // 若是,使對應的Key數組中的值為 FALSE
KillGLWindow(); // 銷毀當前的窗口
fullscreen=!fullscreen; // 切換 全屏 / 窗口 模式
// 重建 OpenGL 窗口(修改)
if (!CreateGLWindow("NeHe’s First Polygon Tutorial",
640,480,16,fullscreen))
{
return 0; // 如果窗口未能創建,程序退出
}
Markus Knauer注:在《OpenGL紅寶書:OpenGL學習的官方指南,第一版》(
OpenGL Programming Guide: The Official Guide to Learning OpenGL, Release 1, J. Neider, T. Davis, M. Woo, Addison-Wesley, 1993)一書中清楚的解釋了NeHe所指的在OpenGL中移動的單位概念:“在OpenGL中真的有英寸和英里的區別嗎?答案是一句話?好揮小M甘雍推淥謀浠歡際俏薜ノ壞摹H綣胍眉粼?1.0到20.0米,英寸、公里等等之間的平面,在OpenGL中您無法做到。唯一的法則是您必須使用一致的度量單位。”
在這一課中,我已試著盡量詳細的解釋與多邊形繪制有關的步驟。并創建了一個繪制三角形和正方形的OpenGL程序。如果您有什么意見或建議請給我電子郵件。如果您認為有什么不對或可以改進,請告訴我。我想做最好的OpenGL教程并對您的反饋感興趣。