版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報(bào)或認(rèn)領(lǐng)
文檔簡介
第二章圖形的繪制
張志華蘭州交通大學(xué)第二章圖形的繪制2.1空間點(diǎn)的繪制最簡單的計(jì)算機(jī)圖形就是在屏幕上某個(gè)位置繪制一個(gè)點(diǎn),并用特定的顏色繪制出來。請看下面的代碼: glBegin(GL_POINTS); glVertex3f(0.0f,0.0f,0.0f); glVertex3f(10.0f,10.0f,10.0f); glEnd();計(jì)算機(jī)中的圖元只是把一組頂點(diǎn)或頂點(diǎn)列表解釋為屏幕上繪制的某些形狀,而頂點(diǎn)是用函數(shù)glVertex3f來定義,該函數(shù)中的參數(shù)指明定義點(diǎn)的x、y和z坐標(biāo)。OpenGL中定義的定點(diǎn)到放在函數(shù)glBegin和glEnd之間,由函數(shù)glBegin的參數(shù)指定繪制圖元的類型,GL_POINTS表示這個(gè)序列中繪制的是單個(gè)的點(diǎn)。注意一個(gè)glBegin/glEnd序列中可以包括任意多個(gè)相同類型的圖元。表2-1列出了glBegin可支持的OpenGL圖元。表2-1glBegin可支持的OpenGL圖元模式圖元類型GL_POINTS將指定的各個(gè)頂點(diǎn)用于創(chuàng)建單個(gè)的點(diǎn)GL_LINES將指定的頂點(diǎn)用于創(chuàng)建線段。每兩個(gè)頂點(diǎn)指定一條單獨(dú)的線段。如果頂點(diǎn)個(gè)數(shù)是奇數(shù),則忽略最后一個(gè)GL_LINE_STRIP將指定的頂點(diǎn)用于創(chuàng)建線條。第一個(gè)頂點(diǎn)之后的每個(gè)頂點(diǎn)指定的是線條延伸到的下一個(gè)點(diǎn)GL_LINE_LOOP特性和GL_LINE_STRIP相似,只不過最后一條線段是在指定的最后一個(gè)和第一個(gè)頂點(diǎn)之間繪制。典型情況下,這用于繪制那些可能違反了GL_POLYGON用法規(guī)則的封閉區(qū)域GL_TRIANGLES將指定的頂點(diǎn)用于構(gòu)造三角形。每三個(gè)頂點(diǎn)指定一個(gè)新三角形。如果頂點(diǎn)個(gè)數(shù)不是三的倍數(shù),多余的頂點(diǎn)將被忽略GL_TRIANGLE_STRIP將指定的頂點(diǎn)用于創(chuàng)建三角條。指定前三個(gè)頂點(diǎn)之后,后繼的每個(gè)頂點(diǎn)與它前面兩個(gè)頂點(diǎn)一起用來構(gòu)造下一個(gè)三角形。每個(gè)頂點(diǎn)三元組(在最初的組之后)會(huì)自動(dòng)重新排列以確保三角形繞法的一致性。GL_TRIANGLE_FAN將指定的頂點(diǎn)用于構(gòu)造三角扇形。第一個(gè)頂點(diǎn)充當(dāng)原點(diǎn),第三個(gè)頂點(diǎn)之后的每個(gè)頂點(diǎn)與它的前一個(gè)頂點(diǎn)還有原點(diǎn)一起組合。GL_QUADS每四個(gè)頂點(diǎn)一組用于構(gòu)造一個(gè)四邊形。如果頂點(diǎn)個(gè)數(shù)不是四的倍數(shù),多余的頂點(diǎn)將被忽略GL_QUADS_STRIP將指定的頂點(diǎn)用于構(gòu)造四條形邊。在第一對頂點(diǎn)之后,每對頂點(diǎn)定義一個(gè)四邊形。和GL_QUADS的頂點(diǎn)順序不一樣,每對頂點(diǎn)以指定順序的逆序使用,以便保證繞法的一致GL_POLYGON將指定的頂點(diǎn)用于構(gòu)造一個(gè)凸多邊形。多邊形的邊緣決不能相交。最后一個(gè)頂點(diǎn)會(huì)自動(dòng)連接到第一個(gè)頂點(diǎn)以確保多邊形是封閉的第二章圖形的繪制glVertex函數(shù)用于指定頂點(diǎn),它可以有2,3,4個(gè)參數(shù)。帶2個(gè)參數(shù)時(shí)指定的是空間點(diǎn)的x,y坐標(biāo),其z坐標(biāo)為默認(rèn)值0,在繪制平面圖形時(shí)常常使用這類函數(shù);帶3個(gè)參數(shù)時(shí)指定的是空間點(diǎn)的x,y和z坐標(biāo);帶4個(gè)參數(shù)時(shí),除了定義空間點(diǎn)的x,y,z坐標(biāo),還有一個(gè)不為0的w坐標(biāo),這樣,點(diǎn)的坐標(biāo)(x,y,z,w)實(shí)際上構(gòu)成了一個(gè)齊次坐標(biāo)。在OpenGL中,我們?nèi)匀皇褂靡?guī)范化齊次坐標(biāo)以保證點(diǎn)的齊次坐標(biāo)與三維坐標(biāo)的一一對應(yīng)關(guān)系,最后指定的空間點(diǎn)的坐標(biāo)為(x/w,y/w,z/w,1),w成了坐標(biāo)值的一個(gè)縮放因子。在OpenGL中繪制一個(gè)點(diǎn)時(shí),點(diǎn)大小的默認(rèn)值是一個(gè)象素??梢杂煤瘮?shù)glPointSize修改這個(gè)值: voidglPointSize(GLfloatsize);第二章圖形的繪制這個(gè)函數(shù)采用一個(gè)參數(shù)來指定畫點(diǎn)時(shí)以象素為單位的近似直徑。但是不是任意大小點(diǎn)都支持,通常使用下面的代碼來獲取點(diǎn)大小的范圍和它們之間最小的中間值: GLfloatsizes[2];//保存繪制點(diǎn)的尺寸范圍 GLfloatstep;//保存繪制點(diǎn)尺寸的步長 glGetFloatv(GL_POINT_SIZE_RANGE,sizes); glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);在數(shù)組sizes中包含兩個(gè)元素,分別保存了glPointSize的最小有效值和最大有效值,而變量step將保存點(diǎn)大小之間允許的最小增量。指定范圍之外的大小不會(huì)被解釋為錯(cuò)誤,而是使用最接近指定值的可支持的最大或最小尺寸。在OpenGL程序中,我們常可以利用離散的點(diǎn)來擬合一些常見的曲線,如圓,螺旋線等等。第二章圖形的繪制2.2直線的繪制使用模式GL_LINES可以在兩點(diǎn)之間畫線,如下面的代碼在兩點(diǎn)(0,0,0)和(10,10,10)之間畫一條直線: glBegin(GL_LINES); glVertex3f(0.0f,0.0f,0.0f); glVertex3f(10.0f,10.0f,10.0f); glEnd();注意,在glBegin/glEnd序列中兩個(gè)頂點(diǎn)指定了一個(gè)圖元(直線),如果序列中指定的點(diǎn)為奇數(shù)個(gè),那么最后一個(gè)頂點(diǎn)將被忽略。有時(shí)我們需要在一系列的頂點(diǎn)之間繪制連續(xù)直線,此時(shí)需要用到GL_LINE_STRIP或GL_LINE_LOOP模式。GL_LINE_STRIP模式可以根據(jù)指定的一系列頂點(diǎn),從一個(gè)頂點(diǎn)到另一個(gè)頂點(diǎn)用連續(xù)的線段畫線。第二章圖形的繪制glBegin(GL_LINE_STRIP); glVertex3f(0.0f,0.0f,0.0f); glVertex3f(10.0f,10.0f,0.0f); glVertex3f(20.0f,5.0f,0.0f);glEnd();上面這段代碼實(shí)際上在xy平面內(nèi)繪制了兩條直線(0,0,0)到(10,0,0)和(0,10,0)到(20,5,0)。特別的,當(dāng)沿著某條曲線指定一系列靠的很近的點(diǎn),使用GL_LINE_STRIP模式可以繪制一條曲線。GL_LINE_LOOP模式與GL_LINE_STRIP模式類似,只是會(huì)在指定的最后一個(gè)頂點(diǎn)與第一個(gè)頂點(diǎn)之間畫最后一條線。
第二章圖形的繪制直線的屬性包括線寬和線型。在OpenGL中可用glLineWidth指定線寬: voidglLineWidth(GLfloatwidth)與點(diǎn)的大小類似,glLineWidth函數(shù)采用一個(gè)參數(shù)來指定要畫的線以象素計(jì)的近似寬度,可以用下面的代碼來獲取線寬范圍和它們之間的最小間隔: GLfloatsizes[2];//保存線寬的尺寸范圍 GLfloatstep;//保存線寬尺寸的最小間隔 glGetFloarv(GL_LINE_WIDTH_RANGE,sizes); glGetFloatv(GL_LINE_WIDTH_GRANULARITY,&step);數(shù)組sizes中保存了glLineWidth的最小有效值和最大有效值,而變量step將保存線寬之間允許的最小增量。OpenGL規(guī)范只要求支持一種線寬:1.0。Microsoft的OpenGL實(shí)現(xiàn)允許線寬從0.5到10.0,最小增量為0.125。第二章圖形的繪制除了修改線寬,可以用虛線或短劃線模式創(chuàng)建直線,為此需要先調(diào)用: glEnable(GL_LINE_STIPPLE);然后,函數(shù)glLineStipple將建立用于畫線的模式: glLineStipple(GLintfactor,GLushortpattern);其中,pattern是一個(gè)16位值,他指定了畫線時(shí)所用的模式。每一位代表線段的一部分是開還是關(guān)。默認(rèn)情況下,每一位對應(yīng)一個(gè)象素,但factor參數(shù)充當(dāng)倍數(shù)可以增加模式的寬度。例如,將factor設(shè)為2會(huì)使模式中的每一位代表一行中2個(gè)象素的開或關(guān)。另外,在應(yīng)用模式時(shí),pattern是逆向使用的,即模式的最低有效位最先作用于指定線段。圖2.1說明了模式0X00FF是如何應(yīng)用到線段上的。第二章圖形的繪制在下面的程序演示了點(diǎn)的大小,線型以及線寬等等,輸出圖形如圖2.2所示。圖2.1點(diǎn)劃模式用于構(gòu)造線段程序清單2.1:點(diǎn)的大小,直線線型和線寬的示例//PointAndLine.c#include<windows.h>#include<gl/glut.h>#include<gl/gl.h>voidRenderScene(void){ glClear(GL_COLOR_BUFFER_BIT);//用當(dāng)前背景色填充窗口 glColor3f(0.0f,0.0f,0.0f);//設(shè)置當(dāng)前的繪圖繪圖RGB顏色 GLfloatsizes[2];//保存繪制點(diǎn)的尺寸范圍 GLfloatstep;//保存繪制點(diǎn)尺寸的步長 GLfloatcurSize;//當(dāng)前繪制的點(diǎn)的大小 glGetFloatv(GL_POINT_SIZE_RANGE,sizes);//獲得點(diǎn)的尺寸范圍 glGetFloatv(GL_POINT_SIZE_GRANULARITY,&step);//獲得點(diǎn)尺寸的步長//繪制不同大小的點(diǎn) curSize=sizes[0]; for(inti=0;i<25;i++) { glPointSize(curSize);//設(shè)置點(diǎn)的大小 glBegin(GL_POINTS); glVertex3f(25.0+i*8,200.0f,0.0f); glEnd(); curSize+=step*2; } //繪制一條寬度為5的直線 glLineWidth(5);//設(shè)置線寬 glBegin(GL_LINES); glVertex3f(25.0f,160.0f,0.0f); glVertex3f(225.0f,160.0f,0.0f); glEnd();//繪制一條虛線 glEnable(GL_LINE_STIPPLE); glLineStipple(1,0x00FF);//設(shè)置點(diǎn)劃線模式 glBegin(GL_LINES); glVertex3f(25.0f,120.0f,0.0f); glVertex3f(225.0f,120.0f,0.0f); glEnd(); //繪制一條寬度為3的點(diǎn)劃線 glLineWidth(3); glLineStipple(1,0xFF0C); glBegin(GL_LINES); glVertex3f(25.0f,80.0f,0.0f); glVertex3f(225.0f,80.0f,0.0f); glEnd();//增加重復(fù)因子繪制的點(diǎn)劃線 glLineStipple(4,0xFF0C); glBegin(GL_LINES); glVertex3f(25.0f,40.0f,0.0f); glVertex3f(225.0f,40.0f,0.0f); glEnd(); glDisable(GL_LINE_STIPPLE); glFlush();//刷新OpenGL命令隊(duì)列}voidChangeSize(GLsizeiw,GLsizeih){ if(h==0) h=1; glViewport(0,0,w,h);//設(shè)置視區(qū)尺寸 //重置坐標(biāo)系統(tǒng) glMatrixMode(GL_PROJECTION); glLoadIdentity(); //建立修剪空間的范圍 if(w<=h) glOrtho(0.0f,250.0f,0.0f,250.0f*h/w,1.0f,-1.0f); else glOrtho(0.0f,250.0f*w/h,0.0f,250.0f,1.0f,-1.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}voidSetupRC(void){ glClearColor(1.0f,1.0f,1.0f,1.0f);//設(shè)置窗口的背景色}voidmain(void){glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB); glutCreateWindow("點(diǎn)與線"); glutDisplayFunc(RenderScene);//設(shè)置當(dāng)前窗口的顯示回調(diào)函數(shù) glutReshapeFunc(ChangeSize);//為當(dāng)前窗口設(shè)置窗口再整形回調(diào)函數(shù) SetupRC(); glutMainLoop();//啟動(dòng)主GLUT事件處理循環(huán)}第二章圖形的繪制在上面的程序中,由于OpenGL使用的是一種狀態(tài)機(jī)制,故此我們在繪制第一條直線前設(shè)置線寬為5,不僅影響了第一條直線,還使繪制的虛線線寬也為5,直到在繪制第一條點(diǎn)劃線前將線寬改為3為止,這樣后面繪制的直線線寬均為3,直到再次修改為止。故此在繪制圖形的時(shí)候,盡可能將狀態(tài)相同或部分狀態(tài)相同的圖形放在一起繪制,可以提高程序的執(zhí)行效率。
圖2.2程序PointAndLine的運(yùn)行結(jié)果第二章圖形的繪制2.3多邊形面的繪制 1.三角形的繪制在OpenGL中,面是由多邊形構(gòu)成的。三角形可能是最簡單的多邊形,它有三條邊??梢允褂肎L_TRIANGLES模式通過把三個(gè)頂點(diǎn)連接到一起而繪出三角形。下面的代碼繪制了一個(gè)三角形:glBegin(GL_TRIANGLES); glVertex2f(0.0,0.0); glVertex2f(15.0,15.0); glVertex2f(30.0,0.0);glEnd(); 注意,這里三角形將被用當(dāng)前選定的顏色填充,如果尚未指定繪圖的顏色,結(jié)果將是不確定的。第二章圖形的繪制使用GL_TRIANGLE_STRIP模式可以繪制幾個(gè)相連的三角形,系統(tǒng)根據(jù)前三個(gè)頂點(diǎn)繪制第一個(gè)多邊形,以后每指定一個(gè)頂點(diǎn),就與構(gòu)成上一個(gè)三角形的后兩個(gè)頂點(diǎn)繪制新的一個(gè)三角形。使用GL_TRIANGLE_FAN模式可以繪制一組相連的三角形,這些三角形繞著一個(gè)中心點(diǎn)成扇形排列。第一個(gè)頂點(diǎn)構(gòu)成扇形的中心,用前三個(gè)頂點(diǎn)繪制出最初的三角形之后,隨后的所有頂點(diǎn)都和扇形中心以及緊跟在它前面的頂點(diǎn)構(gòu)成下一個(gè)三角形,此時(shí)是以順時(shí)針方向穿過頂點(diǎn)。這兩種模式的推進(jìn)如圖2.3和圖2.4所示。圖2.3GL_TRIANGLE_STRIP模式
圖2.4GL_TRIANGLE_FAN模式第二章圖形的繪制2.繞法 在繪制三角形的過程中,三個(gè)頂點(diǎn)將三角形封閉的過程是有序的,即三角形的構(gòu)成路徑具有方向性,我們把指定頂點(diǎn)時(shí)順序和方向的組合稱為“繞法”。比如上面的例子中畫出的三角形的繞法就是順時(shí)針的,若把后兩個(gè)頂點(diǎn)的位置互換,就得到了逆時(shí)針繞法。繞法是任何多邊形圖元的一個(gè)重要特性。一般默認(rèn)情況下,OpenGL認(rèn)為逆時(shí)針繞法的多邊形是正對著的,這一特性對于希望給多邊形的正面和背面賦予不同的物理特性十分有用。如果要反轉(zhuǎn)OpenGL的默認(rèn)行為,可以調(diào)用函數(shù): glFrontFace(GL_CW); CL_CW告訴OpenGL應(yīng)該把順時(shí)針纏繞的多邊形為正對著的。為了改回把逆時(shí)針繞法視為正面,可以使用CL_CCW。
第二章圖形的繪制3.明暗處理在繪制多邊形時(shí),我們常常要指定繪制的顏色,而在OpenGL中,顏色實(shí)際上是對各個(gè)頂點(diǎn)而不是對各個(gè)多邊形指定的。多邊形的輪廓或者內(nèi)部用單一的顏色或許多不同的顏色來填充的處理方式稱為明暗處理。在OpenGL中,用單一顏色處理的稱為平面明暗處理(FlatShading),用許多不同顏色處理的稱為光滑明暗處理(SmoothShading),也稱為Gourand明暗處理(GourandShading)。 設(shè)置明暗處理模式的函數(shù)為: voidglShadeModel(GLenummode); 其中參數(shù)mode的取值為GL_FLAT或GL_SMOOTH,分別表示平面明暗處理和光滑明暗處理。應(yīng)用平面明暗處理模式時(shí),多邊形內(nèi)每個(gè)點(diǎn)的法向一致,且顏色也一致,OpenGL用指定多邊形最后一個(gè)頂點(diǎn)時(shí)的當(dāng)前顏色作為填充多邊形的純色;應(yīng)用光滑明暗處理模式時(shí),多邊形所有點(diǎn)的法向是由內(nèi)插生成的,具有一定的連續(xù)性,因此每個(gè)點(diǎn)的顏色也相應(yīng)內(nèi)插,故呈現(xiàn)不同色。這種模式下,插值方法采用的是雙線性插值法第二章圖形的繪制Gouraud明暗處理通常算法為:先用多邊形頂點(diǎn)的光強(qiáng)線性插值出當(dāng)前掃描線與多邊形邊交點(diǎn)處的光強(qiáng),然后再用交點(diǎn)的光強(qiáng)線插值處掃描線位于多邊形內(nèi)區(qū)段上每一象素處的光強(qiáng)值。圖2.5中顯示出一條掃描線與多邊形相交,交線的端點(diǎn)是A點(diǎn)和B點(diǎn),P點(diǎn)是掃描線上位于多邊形內(nèi)的任一點(diǎn),多邊形三個(gè)頂點(diǎn)的光強(qiáng)分別為I1、I2和I3。取A點(diǎn)的光強(qiáng)Ia為I1和I2的線性插值,B點(diǎn)的光強(qiáng)Ib為I1和I3的線性插值,P點(diǎn)的光強(qiáng)Ip則為Ia和Ib的線性插值。圖2.5Gouraud明暗處理第二章圖形的繪制采用Gouraud明暗處理不但可以使用多邊形表示的曲面光強(qiáng)連續(xù),而且計(jì)算量很小。這種算法還可以以增量的形式改進(jìn),且能用硬件直接實(shí)現(xiàn)算法,從而廣泛用于計(jì)算機(jī)實(shí)時(shí)圖形生成。第二章圖形的繪制4.多邊形的模式 多邊形不是必須用當(dāng)前顏色填充的。默認(rèn)情況下繪制的多邊形是實(shí)心的,但可以通過指定把多邊形繪制為輪廓或只是點(diǎn)(只畫出頂點(diǎn))來修改這項(xiàng)默認(rèn)行為。函數(shù)glPolygonMode允許把多邊形渲染為填充的實(shí)心、輪廓線或只是點(diǎn)。另外,可以把這項(xiàng)渲染模式應(yīng)用到多邊形的兩面或只應(yīng)用到正面或背面。使用下面的函數(shù)可以改變多邊形模式: glPolygonMode(Glenumface,Glenummode);其中,參數(shù)face指定多邊形的哪一面受模式改變的影響——GL_FRONT,GL_BACK或GL_FRONT_AND_BACK。參數(shù)mode用于指定新的繪圖模式。GL_FILL是默認(rèn)值,生成填充的多邊形;GL_LINE生成多邊形的輪廓;而GL_POINT只畫出頂點(diǎn)。GL_LINE和GL_POINT繪制的點(diǎn)和線受glEdgeFlag所設(shè)置邊緣標(biāo)記的影響。
第二章圖形的繪制5.多邊形的繪制規(guī)則在使用大量多邊形構(gòu)造一個(gè)復(fù)雜表面時(shí),有兩條重要規(guī)則。第一條規(guī)則是所有多邊形都必須是平面的,也就是說,多邊形的所有頂點(diǎn)必須位于一個(gè)平面上,不能在空間中扭曲。第二條規(guī)則是多邊形的邊緣決不能相交,而且多邊形必須是凸的。如果有任意兩條邊交叉,就稱這個(gè)多邊形與自己相交。“凸的”是指任意經(jīng)過多邊形的直線進(jìn)入和離開多邊形的次數(shù)不超過一次。對于非凸多邊形,可以把它分割成幾個(gè)凸多邊形(通常是三角形),再將它繪制出來。這樣又出現(xiàn)了一個(gè)問題,如果這樣的多邊形被填充時(shí)看不到任何邊緣,但如果切換到輪廓圖形,就會(huì)看到組成大表面的所有小三角形,這會(huì)分散你的注意力。OpenGL提供了一個(gè)特殊標(biāo)記來處理這些邊緣,稱為邊緣標(biāo)記。在指定頂點(diǎn)的列表時(shí),通過設(shè)置和清除邊緣標(biāo)記,可以通知OpenGL哪些線段被認(rèn)為是邊線(圍繞圖形邊界的線),哪些線段不是(不應(yīng)該顯示的內(nèi)部線段)。glEdgeFlag函數(shù)用一個(gè)參數(shù)把邊緣標(biāo)記設(shè)為True或false。當(dāng)函數(shù)被設(shè)置為True時(shí),后面的頂點(diǎn)將標(biāo)記出邊界線段的起點(diǎn)。第二章圖形的繪制第二章圖形的繪制下面的程序演示了一個(gè)三角形,可以通過菜單修改其狀態(tài)。程序清單2.2:三角形的繪制//Triangle.c#include<windows.h>#include<gl/gl.h>#include<gl/glut.h>//旋轉(zhuǎn)參數(shù)staticGLfloatxRot=0.0f;staticGLfloatyRot=0.0f;//確定多邊形繞法的方向BOOLbWinding=TRUE;voidSetupRC(void)//初始化窗口{glClearColor(0.0f,0.0f,0.0f,1.0f);//設(shè)置窗口背景顏色為黑色}voidChangeSize(intw,inth){ if(h==0) h=1; glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity(); if(w<=h) glOrtho(-100.0f,100.0f,-100.0f*h/w,100.0f*h/w,-100.0f,100.0f); else glOrtho(-100.0f*w/h,100.0f*w/h,-100.0f,100.0f,-100.0f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}//在窗口中繪制圖形voidRenderScene(void){ glClear(GL_COLOR_BUFFER_BIT); //旋轉(zhuǎn)圖形 glPushMatrix(); glRotatef(xRot,1.0f,0.0f,0.0f); glRotatef(yRot,0.0f,1.0f,0.0f); //設(shè)置點(diǎn)的大小以及線寬 glPointSize(5); glLineWidth(5);//設(shè)置多邊形繞法的方向是順時(shí)針還是逆時(shí)針 if(bWinding) glFrontFace(GL_CW); else glFrontFace(GL_CCW); /繪制三角形 glBegin(GL_TRIANGLES); glColor3f(0.0f,1.0f,0.0f); glVertex3f(0,60,0); glColor3f(1.0f,0.0f,0.0f); glVertex3f(-60,-60,0); glColor3f(0.0f,0.0f,1.0f); glVertex3f(60,-60,0); glEnd(); glPopMatrix(); glutSwapBuffers();//刷新命令緩沖區(qū)}voidSpecialKeys(intkey,intx,inty){ if(key==GLUT_KEY_UP) xRot-=5.0f; if(key==GLUT_KEY_DOWN) xRot+=5.0f; if(key==GLUT_KEY_LEFT) yRot-=5.0f; if(key==GLUT_KEY_RIGHT) yRot+=5.0f; if(xRot>356.0f) xRot=0.0f; if(xRot<-1.0f) xRot=355.0f; if(yRot>356.0f) yRot=0.0f; if(yRot<-1.0f) yRot=355.0f; //刷新窗口 glutPostRedisplay();}voidProcessMenu(intvalue){ switch(value) { case1: //修改多邊形正面為填充模式 glPolygonMode(GL_FRONT,GL_FILL); break; case2: //修改多邊形正面為線模式 glPolygonMode(GL_FRONT,GL_LINE); break; case3: //修改多邊形正面為點(diǎn)充模式 glPolygonMode(GL_FRONT,GL_POINT); break; case4: //修改多邊形反面為填充模式 glPolygonMode(GL_FRONT,GL_FILL); break; case5: //修改多邊形反面為線模式 glPolygonMode(GL_FRONT,GL_LINE); break;
case6://修改多邊形反面為點(diǎn)模式 glPolygonMode(GL_FRONT,GL_POINT); break; case7: //設(shè)置多邊形的陰影模式為平面明暗模式 glShadeModel(GL_FLAT); break; case8: //設(shè)置多邊形的陰影模式為光滑明暗模式 glShadeModel(GL_SMOOTH); break; case9: bWinding=!bWinding; break; default: break; } glutPostRedisplay();}intmain(intargc,char*argv[]){ intnModeMenu; intnMainMenu; intnColorMenu; glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutCreateWindow("多邊形演示"); glutReshapeFunc(ChangeSize); glutSpecialFunc(SpecialKeys);//設(shè)置特殊鍵響應(yīng)回調(diào)函數(shù) glutDisplayFunc(RenderScene);//創(chuàng)建一個(gè)子菜單并定義菜單回調(diào)函數(shù) nModeMenu=glutCreateMenu(ProcessMenu); //添加菜單項(xiàng),1表示選擇菜單條目時(shí)傳遞的參數(shù)值 glutAddMenuEntry("正面多邊形填充模式",1); glutAddMenuEntry("正面線框模型",2); glutAddMenuEntry("正面點(diǎn)模式",3); glutAddMenuEntry("反面多邊形填充模式",4); glutAddMenuEntry("反面線框模型",5); glutAddMenuEntry("反面點(diǎn)模式",6); //增加一個(gè)子菜單 nColorMenu=glutCreateMenu(ProcessMenu); glutAddMenuEntry("平面明暗模式",7); glutAddMenuEntry("光滑明暗模式",8);//創(chuàng)建主菜單 nMainMenu=glutCreateMenu(ProcessMenu); glutAddSubMenu("多邊形模式",nModeMenu); glutAddSubMenu("顏色模式",nColorMenu); glutAddMenuEntry("改變繞法",9); //將創(chuàng)建的菜單與右鍵關(guān)聯(lián),即把菜單設(shè)置為右鍵彈出式菜單 glutAttachMenu(GLUT_RIGHT_BUTTON); SetupRC(); glutMainLoop(); return0;}第二章圖形的繪制在程序4中,我們增加了特殊鍵的控制,利用函數(shù)glutSpecialFunc(SpecialKeys)設(shè)置了特殊鍵響應(yīng)回調(diào)函數(shù),并在這個(gè)函數(shù)中修改了兩個(gè)用于控制x和y方向旋轉(zhuǎn)角度的參數(shù)xRot,yRot,然后在顯示回調(diào)函數(shù)RenderScene中增加以下代碼: glPushMatrix(); glRotatef(xRot,1.0f,0.0f,0.0f); glRotatef(yRot,0.0f,1.0f,0.0f);……glPopMatrix();這樣使得通過方向鍵可以使整個(gè)場景繞著x軸和y軸旋轉(zhuǎn),關(guān)于旋轉(zhuǎn)變換的內(nèi)容在第三章將詳細(xì)介紹。第二章圖形的繪制2.4平面多面體的繪制最常見的形體是平面多面體,平行多面體是由多個(gè)多邊形表面構(gòu)成的封閉實(shí)體,這樣我們可以通過構(gòu)造平面多面體的各個(gè)面組合而成。當(dāng)然,在glut庫中還提供了一些常見實(shí)體的繪制函數(shù),如球體、圓環(huán)、正四面體等,參見附錄中的相關(guān)內(nèi)容。下面的例子演示了利用4個(gè)三角形構(gòu)造出了一個(gè)三棱錐的過程,其輸出如圖2.6所示。程序清單2.3:構(gòu)造三棱錐#include<windows.h>#include<gl/gl.h>#include<gl/glut.h>//旋轉(zhuǎn)參數(shù)staticGLfloatxRot=0.0f;staticGLfloatyRot=0.0f;BOOLbDepth=FALSE;//深度測試開關(guān)BOOLbCull=FALSE;//剔除開關(guān)voidSetupRC(void){//設(shè)置窗口背景顏色為黑色glClearColor(0.0f,0.0f,0.0f,1.0f);//指定多邊形的陰影模式為平面陰暗模式glShadeModel(GL_FLAT);}voidChangeSize(intw,inth){ if(h==0) h=1;glViewport(0,0,w,h); glMatrixMode(GL_PROJECTION); glLoadIdentity();if(w<=h) glOrtho(-100.0f,100.0f,-100.0f*h/w,100.0f*h/w,-100.0f,100.0f);else glOrtho(-100.0f*w/h,100.0f*w/h,-100.0f,100.0f,-100.0f,100.0f); glMatrixMode(GL_MODELVIEW); glLoadIdentity();}//在窗口中繪制圖形voidRenderScene(void){ //清除顏色及深度緩沖區(qū) glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); //是否開啟設(shè)度測試 if(bDepth) glEnable(GL_DEPTH_TEST); else glDisable(GL_DEPTH_TEST);//是否打開剔除 if(bCull) glEnable(GL_CULL_FACE); else glDisable(GL_CULL_FACE);//旋轉(zhuǎn)圖形 glPushMatrix(); glRotatef(xRot,1.0f,0.0f,0.0f); glRotatef(yRot,0.0f,1.0f,0.0f); //指定順時(shí)針繞法的多邊形為多邊形正面 glFrontFace(GL_CW); //繪制三棱錐的三個(gè)棱面,他們的顏色分別為紅、綠、藍(lán) glBegin(GL_TRIANGLE_FAN); glVertex3f(0.0,0.0,80.0); glVertex3f(0.0,50.0,0.0); glColor3f(1.0,0.0,0.0); glVertex3f(50.0,-50.0,0.0); glColor3f(0.0,1.0,0.0); glVertex3f(-50.0,-50.0,0.0); glColor3f(0.0,0.0,1.0); glVertex3f(0.0,50.0,0.0); glEnd();//繪制三棱錐的底面,其顏色為黃色 glBegin(GL_TRIANGLE_FAN); glVertex3f(0.0,50.0,0.0); glVertex3f(50.0,-50.0,0.0); glColor3f(1.0,1.0,0.0); glVertex3f(-50.0,-50.0,0.0); glEnd(); glPopMatrix(); //刷新命令緩沖區(qū) glutSwapBuffers();}voidSpecialKeys(intkey,intx,inty){ if(key==GLUT_KEY_UP) xRot-=5.0f; if(key==GLUT_KEY_DOWN) xRot+=5.0f; if(key==GLUT_KEY_LEFT) yRot-=5.0f; if(key==GLUT_KEY_RIGHT) yRot+=5.0f; if(xRot>356.0f) xRot=0.0f; if(xRot<-1.0f) xRot=355.0f; if(yRot>356.0f) yRot=0.0f; if(yRot<-1.0f) yRot=355.0f; //刷新窗口 glutPostRedisplay();}voidProcessMenu(intvalue){ switch(value) { case1: bDepth=!bDepth; break; case2: bCull=!bCull; break; default: break; } glutPostRedisplay();}intmain(intargc,char*argv[]){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE|GLUT_RGB); glutCreateWindow
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會(huì)有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲(chǔ)空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時(shí)也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 2024年汽車銷售合同擔(dān)保服務(wù)模板附車輛改裝服務(wù)3篇
- 2024年短期公租房租賃合同
- 崗位職責(zé)表課程設(shè)計(jì)
- 2024幼兒園發(fā)展規(guī)劃(35篇)
- 基于機(jī)器學(xué)習(xí)的古代繪畫修復(fù)與復(fù)原技術(shù)研究
- 2024年?duì)I銷工作計(jì)劃(59篇)
- 沼氣池儲(chǔ)氣罐課程設(shè)計(jì)
- 線描西蘭花課程設(shè)計(jì)
- 英漢互譯系統(tǒng)的課程設(shè)計(jì)
- 物流行業(yè)運(yùn)輸司機(jī)工作總結(jié)
- 藝術(shù)學(xué)概論學(xué)習(xí)通超星期末考試答案章節(jié)答案2024年
- 托育機(jī)構(gòu)食品安全培訓(xùn)
- 2024年區(qū)域牛羊肉獨(dú)家代理銷售協(xié)議
- 2024旅行社承包經(jīng)營合同
- 地下車庫地面改造施工方案
- 成人有創(chuàng)機(jī)械通氣氣道內(nèi)吸引技術(shù)操作標(biāo)準(zhǔn)解讀
- 《護(hù)患溝通》課件
- 洗浴用品購銷合同模板
- 電能質(zhì)量-公用電網(wǎng)諧波
- 電火灶-編制說明
- 幼兒園幼小銜接方案模板
評論
0/150
提交評論