




版權(quán)說明:本文檔由用戶提供并上傳,收益歸屬內(nèi)容提供方,若內(nèi)容存在侵權(quán),請進(jìn)行舉報或認(rèn)領(lǐng)
文檔簡介
1、實(shí)驗一基本圖元的繪制及其簡單幾何變換前言O(shè)penGL作為當(dāng)前主流的圖形 API之一,它在一些場合具有比DirectX更優(yōu)越的特性。1、與C語言緊密結(jié)合。OpenGL命令最初就是用 C語言函數(shù)來進(jìn)行描述的,對于學(xué)習(xí)過C語言的人來講,OpenGL是容易理解和學(xué)習(xí)的。如果你曾經(jīng)接觸過TC的graphics.h,你會發(fā)現(xiàn),使用OpenGL作圖甚至比TC更加簡單。2、強(qiáng)大的可移植性。微軟的Direct3D雖然也是十分優(yōu)秀的圖形API,但它只用于 Windows系統(tǒng)(現(xiàn)在還要加上一個XBOX游戲機(jī))。而OpenGL不僅用于 Windows ,還可以用于 Unix/Linux等其它系統(tǒng),它甚至在大型計算機(jī)、
2、各種 專業(yè)計算機(jī)(如:醫(yī)療用顯示設(shè)備)上都有應(yīng)用。并且, OpenGL的基本命令都做到了硬件無關(guān),甚至是 平臺無關(guān)。3、高性能的圖形渲染。OpenGL是一個工業(yè)標(biāo)準(zhǔn),它的技術(shù)緊跟時代,現(xiàn)今各個顯卡廠家無一不對OpenGL提供強(qiáng)力支持,激烈的競爭中使得OpenGL性能一直領(lǐng)先。總之,OpenGL是一個很NB的圖形軟件接口。至于究竟有多NB ,去看看DOOM3和QUAKE4等專業(yè)游戲就知道了。OpenGL官方網(wǎng)站(英文) HYPERLINK 1、學(xué)習(xí)OpenGL前的準(zhǔn)備工作第一步,選擇一個編譯環(huán)境現(xiàn)在 Windows系統(tǒng)的主流編譯環(huán)境有 Visual Studio , Broland C+ Bui
3、lder , Dev-C+等,它們都是支持 OpenGL 的。但這里我們選擇 Visual Studio 2005作為學(xué)習(xí)OpenGL的環(huán)境。第二步,安裝GLUT工具包GLUT不是OpenGL所必須的,但它會給我們的學(xué)習(xí)帶來一定的方便,推薦安裝。Windows環(huán)境下的GLUT下載地址:(大小約為150k) HYPERLINK /resources/libraries/glut/glutdlls37beta.zip /resources/libraries/glut/glutdlls37beta.zip無法從以上地址下載的話請使用下面的連接: HYPERLINK /upfile/20060731
4、1626279.zip /upfile/200607311626279.zipWindows環(huán)境下安裝GLUT的步驟:1、將下載的壓縮包解開,將得到 5個文件2、在 我的電腦”中搜索“gl.h,并找到其所在文件夾,把解壓得到的glut.h放到這個文件夾。3、把解壓得到的glut.lib和glut32.lib放到靜態(tài)函數(shù)庫所在文件夾4、把解壓得到的glut.dll和glut32.dll放到操作系統(tǒng)目錄下面的system32文件夾內(nèi)。(典型的位置為:C:WindowsSystem32)第三步,建立一個 OpenGL工程這里以 VisualStudio2005 為例。選擇 File-New-Proj
5、ect ,然后選擇 Win32 Console Application ,選擇一個名字,然后按 OK。在談出的對話框左邊點(diǎn) Application Settings ,找到Empty project并勾上,選擇 Finish。然后向該工程添加一個代碼文件,取名為“OpenGL.C,注意用.c來作為文件結(jié)尾。搞定了,就跟平時的工程沒什么兩樣的第一個OpenGL程序 一個簡單的OpenGL程序如下:#include void myDisplay(void)(glClear(GL_COLOR_BUFFER_BIT);glRectf(-0.5f, -0.5f, 0.5f, 0.5f);glFlush(
6、);int main(int argc, char *argv)(glutInit(&argc, argv);glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);glutInitWindowPosition(100, 100);glutInitWindowSize(400, 400);glutCreateWindow(第一個 OpenGL 程序);glutDisplayFunc(&myDisplay);glutMainLoop();return 0;該程序的作用是在一個黑色的窗口中央畫一個白色的矩形。下面對各行語句進(jìn)行說明。首先,需要包含頭文件 #inclu
7、de ,這是GLUT的頭文件。本來OpenGL程序一般還要包含 和 ,但GLUT的頭文件中已經(jīng)自動將這兩個文件包含 了,不必再次包含。然后看 main函數(shù)。int main(int argc, char *argv口),這個是帶命令行參數(shù)的main函數(shù),各位應(yīng)該見過吧?沒見過的同志們請多翻翻書,等弄明白了再往下看。注意main函數(shù)中的各語句,除了最后的 return之外,其余全部以 glut開頭。這種以glut開頭的函數(shù)都是 GLUT工具包所提供的函數(shù),下面對用到的幾個函數(shù)進(jìn)行介紹。1、glutInit ,對GLUT進(jìn)行初始化,這個函數(shù)必須在其它的GLUT使用之前調(diào)用一次。其格式比較死板,一般
8、照抄這句glutInit(&argc, argv)就可以了。2、glutInitDisplayMode,設(shè)置顯示方式,其中GLUT_RGB表示使用RGB顏色,與之對應(yīng)的還有 GLUT_INDEX (表示使用索引顏色)GLUT_SINGLE表示使用單緩沖,與之對應(yīng)的還有GLUT_DOUBLE (使用雙緩沖)。更多信息,請自己 Googleo當(dāng)然以后的教程也會有一些講解。3、glutInitWindowPosition ,這個簡單,設(shè)置窗口在屏幕中的位置。4、glutInitWindowSize ,這個也簡單,設(shè)置窗口的大小。5、glutCreateWindow ,根據(jù)前面設(shè)置的信息創(chuàng)建窗口。參數(shù)
9、將被作為窗口的標(biāo)題。注意:窗口被創(chuàng)建后, 并不立即顯示到屏幕上。需要調(diào)用glutMainLoop才能看到窗口。6、glutDisplayFunc ,設(shè)置一個函數(shù),當(dāng)需要進(jìn)行畫圖時,這個函數(shù)就會被調(diào)用。(這個說法不夠準(zhǔn)確,但準(zhǔn)確的說法可能初學(xué)者不太好理解,暫時這樣說吧)。7、glutMainLoop ,進(jìn)行一個消息循環(huán)。(這個可能初學(xué)者也不太明白,現(xiàn)在只需要知道這個函數(shù)可以顯示 窗口,并且等待窗口關(guān)閉后才會返回,這就足夠了。 )在glutDisplayFunc函數(shù)中,我們設(shè)置了 當(dāng)需要畫圖時,請調(diào)用 myDisplay函數(shù)。于是myDisplay函數(shù)就 用來畫圖。觀察 myDisplay中的三個
10、函數(shù)調(diào)用,發(fā)現(xiàn)它們都以 gl開頭。這種以gl開頭的函數(shù)都是 OpenGL 的標(biāo)準(zhǔn)函數(shù),下面對用到的函數(shù)進(jìn)行介紹。1、glClear,清除。GL_COLOR_BUFFER_BIT 表示清除顏色,glClear函數(shù)還可以清除其它的東西,但這里 不作介紹。2、glRectf,畫一個矩形。四個參數(shù)分別表示了位于對角線上的兩個點(diǎn)的橫、縱坐標(biāo)。3、glFlush ,保證前面的 OpenGL命令立即執(zhí)行(而不是讓它們在緩沖區(qū)中等待)。其作用跟fflush(stdout)類似。2、繪制簡單的幾何圖形2.1繪圖前的一些準(zhǔn)備工作(1)在開始繪圖前,屏幕上可能有一些圖形,OpenGL存儲了這些圖形繪圖狀態(tài)的信息,所
11、以必須清除當(dāng)前窗口的內(nèi)容,以免影響繪圖效果,可以用:void glClearC010r(GLclampf red, GLclampf green, GLclampf blue, GLclampf alpha) 給定當(dāng)前屏幕的背景設(shè)置顏色。Red,green,blue,alpha為RGBA顏色值。voidglClear(GLbitfield mask);清楚指定的緩沖區(qū)。mask的取值有:GL_COLOR_BUFFER_BIT ,顏色緩沖區(qū) GL_DEPTH_BUFFER_BIT ,深度緩沖區(qū) GL_ACCUM_BUFFER_BIT ,累力口緩沖區(qū) GL_STENCIL_BUFFER_BIT ,
12、模板緩沖區(qū)(2)畫點(diǎn)、直線和多邊形的思路我們知道數(shù)學(xué)(具體的說,是幾何學(xué))中有點(diǎn)、直線和多邊形的概念,但這些概念在計算機(jī)中會有所 不同。數(shù)學(xué)上的點(diǎn),只有位置,沒有大小。但在計算機(jī)中,無論計算精度如何提高,始終不能表示一個無 窮小的點(diǎn)。另一方面,無論圖形輸出設(shè)備(例如,顯示器)如何精確,始終不能輸出一個無窮小的點(diǎn)。一 般情況下,OpenGL中的點(diǎn)將被畫成單個的像素(像素的概念,請自己搜索之),雖然它可能足夠小,但并不會是無窮小。同一像素上,OpenGL可以繪制許多坐標(biāo)只有稍微不同的點(diǎn),但該像素的具體顏色將取決于OpenGL的實(shí)現(xiàn)。當(dāng)然,過度的注意細(xì)節(jié)就是鉆牛角尖,我們大可不必花費(fèi)過多的精力去研究
13、多個點(diǎn)如何畫到同一像素上同樣的,數(shù)學(xué)上的直線沒有寬度,但 OpenGL的直線則是有寬度的。同時, OpenGL的直線必須是有 限長度,而不是像數(shù)學(xué)概念那樣是無限的。可以認(rèn)為,OpenGL的直線”概念與數(shù)學(xué)上的 線段”接近,它可以由兩個端點(diǎn)來確定。多邊形是由多條線段首尾相連而形成的閉合區(qū)域。OpenGL規(guī)定,一個多邊形必須是一個凸多邊形”(其定義為:多邊形內(nèi)任意兩點(diǎn)所確定的線段都在多邊形內(nèi),由此也可以推導(dǎo)出,凸多邊形不能是空心的)。多邊形可以由其邊的端點(diǎn)(這里可稱為頂點(diǎn))來確定。(注意:如果使用的多邊形不是凸多邊形,則最后輸出的效果是未定義的 一一OpenGL為了效率,放寬了檢查,這可能導(dǎo)致顯示
14、錯誤。要避免這個錯誤,盡量 使用三角形,因為三角形都是凸多邊形)可以想象,通過點(diǎn)、直線和多邊形,就可以組合成各種幾何圖形。甚至于,你可以把一段弧看成是很 多短的直線段相連,這些直線段足夠短,以至于其長度小于一個像素的寬度。這樣一來弧和圓也可以表示 出來了。通過位于不同平面的相連的小多邊形,我們還可以組成一個曲面”。(3)在OpenGL中指定頂點(diǎn)由以上的討論可以知道,集”是一切的基礎(chǔ)。如何指定一個點(diǎn)呢?OpenGL提供了一系列函數(shù)。它們都以glVertex開頭,后面跟一個數(shù)字和12個字母。例如:glVertex2dglVertex2fglVertex3fglVertex3fv等等。數(shù)字表示參數(shù)的
15、個數(shù),2表示有兩個參數(shù),3表示三個,4表示四個(我知道有點(diǎn)羅嗦 )。 字母表示參數(shù)的類型,s表示16位整數(shù)(OpenGL中將這個類型定義為 GLshort),i表示32位整數(shù)(OpenGL中將這個類型定義為 GLint和GLsizei),f表示32位浮點(diǎn)數(shù)(OpenGL中將這個類型定義為 GLfloat和GLclampf), d表示64位浮點(diǎn)數(shù)(OpenGL中將這個類型定義為 GLdouble和GLclampd)。v表示傳遞的幾個參數(shù)將使用指針的方式,見下面的例子。這些函數(shù)除了參數(shù)的類型和個數(shù)不同以外,功能是相同的。例如,以下五個代碼段的功能是等效的:(一)glVertex2i(1,3);(二
16、)glVertex2f(1.0f, 3.0f);(三)glVertex3f(1.0f, 3.0f, 0.0f);(四)glVertex4f(1.0f, 3.0f, 0.0f, 1.0f);(五)GLfloat VertexArr3 = 1.0f, 3.0f, 0.0f;glVertex3fv(VertexArr3);以后我們將用glVertex*來表示這一系列函數(shù)。注意:OpenGL的很多函數(shù)都是采用這樣的形式,一個相同的前綴再加上參數(shù)說明標(biāo)記,這一點(diǎn)會隨著學(xué) 習(xí)的深入而有更多的體會。(4) OpenGL要求:指定頂點(diǎn)的命令必須包含在glBegin函數(shù)之后,glEnd函數(shù)之前(否則指定的頂點(diǎn)將
17、被忽略)。并由glBegin來指明如何使用這些點(diǎn)。例如:glBegin(GL_POINTS);glVertex2f(0.0f, 0.0f);glVertex2f(0.5f, 0.0f);glEnd();注意函數(shù) glBegin(GLenum mode);其mode的值見下表:GL_POINTS , 一系列獨(dú)立的點(diǎn)GL_LINES ,每兩點(diǎn)相連成為線段GL_POLYGON ,簡單、凸多邊形的邊界GL_TRIANGLES ,三點(diǎn)相連成為一個三角形GL_QUADS ,四點(diǎn)相連成為一個四邊形GL_LINE_STRIP ,頂點(diǎn)相連成為一系列線段GL_LINE_LOOP ,頂點(diǎn)相連成為一系列線段,連接最后
18、一點(diǎn)與第一點(diǎn)GL_TRIANGLE_STRIP ,相連的三角形帶GL_TRIANGLE_FAN ,相連的三角形扇形GL_QUAD_STRIP ,相連的四邊形帶每種方式的大致效果見下圖:* M4V0* 3GL POINTSIANGLE_FAN(5)畫幾何圖的程序框架程序代碼:void myDisplay(void)(glClear(GL_COLOR_BUFFER_BIT);glBegin( /*在這里填上你所希望的模式*/ );/*在這里使用glVertex*系歹U函數(shù)*/*指定你所希望的頂點(diǎn)位置*/glEnd();glFlush();)把這段代碼改成你喜歡的樣子,然后用它替換第一課中的myDi
19、splay函數(shù),編譯后即可運(yùn)行。兩個例子例一、畫一個圓/*正四邊形,正五邊形,正六邊形,直到正n邊形,當(dāng)n越大時,這個圖形就越接近圓當(dāng)n大到一定程度后,人眼將無法把它跟真正的圓相區(qū)別這時我們已經(jīng)成功的畫出了一個圓”(注:畫圓的方法很多,這里使用的是比較簡單,但效率較低的一種)試修改下面的const int n的值,觀察當(dāng)n=3,4,5,8,10,15,20,30,50等不同數(shù)值時輸出的變化情況將GL_POLYGON改為GL_LINE_LOOP 、 GL_POINTS等其它方式,觀察輸出的變化情況*/#include const int n = 20;const GLfloat R = 0.5f
20、;const GLfloat Pi = 3.1415926536f;void myDisplay(void)int i;glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_POL YGON);for(i=0; in; +i)glVertex2f(R*cos(2*Pi/n*i), R*sin(2*Pi/n*i);glEnd();glFlush();例二、畫一個五角星/*設(shè)五角星的五個頂點(diǎn)分布位置關(guān)系如下:AE BD C首先,根據(jù)余弦定理列方程,計算五角星的中心到頂點(diǎn)的距離a(假設(shè)五角星對應(yīng)正五邊形的邊長為.0)a = 1 / (2-2*cos(72*Pi/180);然
21、后,根據(jù)正弦和余弦的定義,計算 B的x坐標(biāo)bx和y坐標(biāo)by,以及C的y坐標(biāo)(假設(shè)五角星的中心在坐標(biāo)原點(diǎn))bx = a * cos(18 * Pi/180);by = a * sin(18 * Pi/180);cy = -a * cos(18 * Pi/180);五個點(diǎn)的坐標(biāo)就可以通過以上四個量和一些常數(shù)簡單的表示出來*/#include const GLfloat Pi = 3.1415926536f;void myDisplay(void)GLfloat a = 1 / (2-2*cos(72*Pi/180);GLfloat bx = a * cos(18 * Pi/180);GLfloat
22、 by = a * sin(18 * Pi/180);GLfloat cy = -a * cos(18 * Pi/180);GLfloatPointA2 = 0, a ,PointB2 = bx, by ,PointC2 = 0.5, cy ,PointD2 = -0.5, cy ,PointE2 = -bx, by ;glClear(GL_COLOR_BUFFER_BIT);/按照A-C-E-B-D-A 的順序,可以一筆將五角星畫出glBegin(GL_LINE_LOOP);glVertex2fv(PointA);glVertex2fv(PointC);glVertex2fv(PointE)
23、;glVertex2fv(PointB);glVertex2fv(PointD);glEnd();glFlush();例三、畫出正弦函數(shù)的圖形/*由于OpenGL默認(rèn)坐標(biāo)彳!只能從-1至U 1 ,(可以修改,但方法留到以后講) 所以我們設(shè)置一個因子 factor,把所有的坐標(biāo)值等比例縮小,這樣就可以畫出更多個正弦周期試修改factor的值,觀察變化情況*/#include const GLfloat factor = 0.1f;void myDisplay(void)GLfloat x;glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_LINES);glVerte
24、x2f(-1.0f, 0.0f);glVertex2f(1.0f, 0.0f);/以上兩個點(diǎn)可以畫 x軸glVertex2f(0.0f, -1.0f);glVertex2f(0.0f, 1.0f);/以上兩個點(diǎn)可以畫 y軸glEnd();glBegin(GL_LINE_STRIP);for(x=-1.0f/factor; x1.0f/factor; x+=0.01f)glVertex2f(x*factor, sin(x)*factor);glEnd();glFlush();)小結(jié)本課講述了點(diǎn)、直線和多邊形的概念,以及如何使用 OpenGL來描述點(diǎn),并使用點(diǎn)來描述幾何圖形。大家可以發(fā)揮自己的想象
25、,畫出各種幾何圖形,當(dāng)然,也可以用GL_LINE_STRIP把很多位置相近的點(diǎn)連接起來,構(gòu)成函數(shù)圖象。如果有興趣,也可以去找一些圖象比較美觀的函數(shù),自己動手,用OpenGL把它畫出來。2.2基本圖形繪制1、關(guān)于點(diǎn)點(diǎn)的大小默認(rèn)為1個像素,但也可以改變之。改變的命令為glPointSize ,其函數(shù)原型如下:void glPointSize(GLfloat size);size必須大于0.0f,默認(rèn)值為1.0f,單位為 像素”。注意:對于具體的 OpenGL實(shí)現(xiàn),點(diǎn)的大小都有個限度的,如果設(shè)置的 size超過最大值,則設(shè)置可能會有 問題。例子:void myDisplay(void) glClea
26、r(GL_COLOR_BUFFER_BIT);glPointSize(5.0f);glBegin(GL_POINTS);glVertex2f(0.0f, 0.0f);glVertex2f(0.5f, 0.5f);glEnd();glFlush(); )2、關(guān)于直線(1)直線可以指定寬度:void glLineWidth(GLfloat width);其用法跟glPointSize類似。(2)畫虛線。首先,使用 glEnable(GL_LINE_STIPPLE);來啟動虛線模式(使用 glDisable(GL_LINE_STIPPLE)可以關(guān)閉之)。 然后,使用glLineStipple來設(shè)置虛
27、線的樣式。void glLineStipple(GLint factor, GLushort pattern);pattern是由1和0組成的長度為16的序列,從最低位開始看,如果為 1,則直線上接下來應(yīng)該畫的factor個點(diǎn)將被畫為實(shí)的;如果為 0,則直線上接下來應(yīng)該畫的factor個點(diǎn)將被畫為虛的。以下是一些例子:PATTERNFACTOR0 x0 OFF1 0 x0OFF 2 0 x0 C OF1 - - -OxOCOF 3 OxAAAA 1OxAAAA 2 OxAAAA 3QxAMA 4 示例代碼:void myDisplay(void) (glClear(GL_COLOR_BUFFE
28、R_BIT);glEnable(GL_LINE_STIPPLE);glLineStipple(2, 0 x0F0F);glLineWidth(10.0f);glBegin(GL_LINES);glVertex2f(0.0f, 0.0f);glVertex2f(0.5f, 0.5f);glEnd(); glFlush();3、關(guān)于多邊形多邊形的內(nèi)容較多,我們將講述以下四個方面。(1)多邊形的兩面以及繪制方式。雖然我們目前還沒有真正的使用三維坐標(biāo)來畫圖,但是建立一些三維的概念還是必要的。從三維的角度來看,一個多邊形具有兩個面。每一個面都可以設(shè)置不同的繪制方式:填充、只繪制邊緣輪 廓線、只繪制頂點(diǎn),
29、其中填充”是默認(rèn)的方式??梢詾閮蓚€面分別設(shè)置不同的方式。glPolygonMode(GL_FRONT, GL_FILL);/ 設(shè)置正面為填充方式glPolygonMode(GL_BACK, GL_LINE);/設(shè)置反面為邊緣繪制方式glPolygonMode(GL_FRONT_AND_BACK, GL_POINT); /設(shè)置兩面均為頂點(diǎn)繪制方式(2)反轉(zhuǎn)一般約定為 頂點(diǎn)以逆時針順序出現(xiàn)在屏幕上的面”為芷面”,另一個面即成為 反面”。生活中常見的物體表面,通常都可以用這樣的正面“和反面”,合理的”被表現(xiàn)出來(請找一個比較透明的礦泉水瓶子,在正對你的一面沿逆時針畫一個圓,并標(biāo)明畫的方向,然后將背面
30、轉(zhuǎn)為正面,畫一個類似的圓,體會一下正面”和反面”。你會發(fā)現(xiàn)正對你的方向,瓶的外側(cè)是正面,而背對你的方向,瓶的內(nèi)側(cè)才是正面。正對你的 內(nèi)側(cè)和背對你的外側(cè)則是反面。這樣一來,同樣屬于瓶的外側(cè)”這個表面,但某些地方算是正面,某些地方卻算是反面了)。但也有一些表面比較特殊。例如麥比烏斯帶”(請自己Google 一下),可以全部使用 芷面”或全部使用 背面”來表不。可以通過glFrontFace函數(shù)來交換 正面”和反面”的概念。glFrontFace(GL_CCW); / 設(shè)置 CCW 方向為 正面”,CCW 即 CounterClockWise ,逆時針 glFrontFace(GL_CW); / 設(shè)
31、置 CW 方向為 芷面,CW 即 ClockWise ,順時針 下面是一個示例程序,請用它替換第一課中的myDisplay函數(shù),并將 glFrontFace(GL_CCW)修改為 glFrontFace(GL_CW),并觀察結(jié)果的變化。void myDisplay(void)(glClear(GL_COLOR_BUFFER_BIT);glPolygonMode(GL_FRONT, GL_FILL); /設(shè)置正面為填充模式glPolygonMode(GL_BACK, GL_LINE); /設(shè)置反面為線形模式glFrontFace(GL_CCW); /設(shè)置逆時針方向為正面glBegin(GL_PO
32、L YGON); /按逆時針繪制一個正方形,在左下方glVertex2f(-0.5f, -0.5f);glVertex2f(0.0f, -0.5f);glVertex2f(0.0f, 0.0f);glVertex2f(-0.5f, 0.0f);glEnd();glBegin(GL_POL YGON); /按順時針繪制一個正方形,在右上方glVertex2f(0.0f, 0.0f);glVertex2f(0.0f, 0.5f);glVertex2f(0.5f, 0.5f);glVertex2f(0.5f, 0.0f);glEnd();glFlush();(3)剔除多邊形表面在三維空間中,一個多邊
33、形雖然有兩個面,但我們無法看見背面的那些多邊形,而一些多邊形雖然是正面 的,但被其他多邊形所遮擋。如果將無法看見的多邊形和可見的多邊形同等對待,無疑會降低我們處理圖 形的效率。在這種時候,可以將不必要的面剔除。首先,使用glEnable(GL_CULL_FACE);來啟動剔除功能(使用 glDisable(GL_CULL_FACE)可以關(guān)閉之) 然后,使用glCullFace來進(jìn)行剔除。glCullFace的參數(shù)可以是 GL_FRONT , GL_BACK或者GL_FRONT_AND_BACK ,分另U表示易U除正面、易U 除反面、剔除正反兩面的多邊形。注意:剔除功能只影響多邊形,而對點(diǎn)和直線
34、無影響。例如,使用glCullFace(GL_FRONT_AND_BACK)后,所有的多邊形都將被剔除,所以看見的就只有點(diǎn)和直線。(4)鏤空多邊形直線可以被畫成虛線,而多邊形則可以進(jìn)行鏤空。首先,使用 glEnable(GL_POLYGON_STIPPLE);來啟動鏤空模式(使用 glDisable(GL_POL YGON_STIPPLE) 可以關(guān)閉之)。然后,使用glPolygonStipple來設(shè)置鏤空的樣式。void glPolygonStipple(const GLubyte *mask);其中的參數(shù)mask指向一個長度為128字節(jié)的空間,它表示了一個32*32的矩形應(yīng)該如何鏤空。其中
35、:第一個字節(jié)表示了最左下方的從左到右(也可以是從右到左,這個可以修改)8個像素是否鏤空(1表示不鏤空,顯示該像素;0表示鏤空,顯示其后面的顏色),最后一個字節(jié)表示了最右上方的8個像素是否鏤空。但是,如果我們直接定義這個mask數(shù)組,像這樣:static GLubyte Mask128 = (0 x000 x00, 0 x00, 0 x00,/這是最下面的一行0 x000 x00, 0 x00, 0 x00,0 x030 x060 x040 x040 x040 x040 x040 x440 x440 x440 x440 x440 x440 x440 x660 x330 x190 x0C0 x07
36、0 x030 x030 x030 x060 x80, 0 x01,0 xC0,0 xC0, 0 x03, 0 x60,0 x60, 0 x06, 0 x20,0 x30, 0 x0C, 0 x20,0 x18, 0 x18, 0 x20,0 x0C, 0 x30, 0 x20,0 x06, 0 x60, 0 x20,0 x03, 0 xC0, 0 x22,0 x01, 0 x80, 0 x22,0 x01, 0 x80, 0 x22,0 x01, 0 x80, 0 x22,0 x01, 0 x80, 0 x22,0 x01, 0 x80, 0 x22,0 x01, 0 x80, 0 x22,0
37、 x01, 0 x80, 0 x66,0 x01, 0 x80, 0 xCC,0 x81,0 x81,0 x98, 0 xC1, 0 x83, 0 x30,0 xE1,0 x87, 0 xE0,0 x3F, 0 xFC, 0 xC0,0 x31, 0 x8C, 0 xC0,0 x3F, 0 xFC, 0 xC0,0 x64, 0 x26, 0 x60,/0 x0C, 0 xCC, 0 x33, 0 x30,0 x180 xCC, 0 x33, 0 x18,0 x100 xC4, 0 x23, 0 x08,0 x100 x63, 0 xC6, 0 x08,0 x100 x30, 0 x0C, 0
38、 x08,0 x100 x18, 0 x18, 0 x08,0 x100 x00, 0 x00, 0 x08 /這是最上面的一行 ;這樣一堆數(shù)據(jù)非常缺乏直觀性,我們需要很費(fèi)勁的去分析,才會發(fā)現(xiàn)它表示的竟然是一只蒼蠅。#include #include void myDisplay(void)static GLubyte Mask128;glClear(GL_COLOR_BUFFER_BIT);glEnable(GL_POL YGON_STIPPLE);glPolygonStipple(Mask);glRectf(-0.5f, -0.5f, 0.0f, 0.0f); /在左下方繪制一個有鏤空效果
39、的正方形glDisable(GL_POL YGON_STIPPLE); glRectf(0.0f, 0.0f, 0.5f, 0.5f); /在右上方繪制一個無鏤空效果的正方形 glFlush();)2.3顏色OpenGL支持兩種顏色模式:一種是 RGBA , 一種是顏色索引模式。無論哪種顏色模式,計算機(jī)都必須為每一個像素保存一些數(shù)據(jù)。不同的是, RGBA模式中,數(shù)據(jù)直接就代表了顏色;而顏色索引模式中,數(shù)據(jù)代表的是一個索引,要得到真正的顏色,還必須去查索引表。1. RGBA顏色RGBA模式中,每一個像素會保存以下數(shù)據(jù):R值(紅色分量)、G值(綠色分量)、B值(藍(lán)色分量)和A值(alpha分量)。
40、其中紅、綠、藍(lán)三種顏色相組合,就可以得到我們所需要的各種顏色,而 alpha不直接 影響顏色,它將留待以后介紹。在RGBA模式下選擇顏色是十分簡單的事情,只需要一個函數(shù)就可以搞定。glColor*系列函數(shù)可以用于設(shè)置顏色,其中三個參數(shù)的版本可以指定R、G、B的值,而A值采用默認(rèn);四個參數(shù)的版本可以分別指定R、G、B、A的值。例如:void glColor3f(GLfloat red, GLfloat green, GLfloat blue);void glColor4f(GLfloat red, GLfloat green, GLfloat blue, GLfloat alpha);(還記得嗎
41、? 3f表示有三個浮點(diǎn)參數(shù)請看第二課中關(guān)于glVertex*函數(shù)的敘述。)將浮點(diǎn)數(shù)作為參數(shù),其中 0.0表示不使用該種顏色,而1.0表示將該種顏色用到最多。例如:glColor3f(1.0f, 0.0f, 0.0f);表示不使用綠、藍(lán)色,而將紅色使用最多,于是得到最純凈的紅色。glColor3f(0.0f, 1.0f, 1.0f); 表示使用綠、藍(lán)色到最多,而不使用紅色。混合的效果就是淺藍(lán)色。glColor3f(0.5f, 0.5f, 0.5f);表示各種顏色使用一半,效果為灰色。注意:浮點(diǎn)數(shù)可以精確到小數(shù)點(diǎn)后若干位,這并不表示計算機(jī)就可以顯示如此多種顏色。實(shí)際上,計算機(jī)可以顯示的顏色種數(shù)將由
42、硬件決定。如果OpenGL找不到精確的顏色,會進(jìn)行類似四舍五入”的處理。大家可以通過改變下面代碼中g(shù)lColor3f的參數(shù)值,繪制不同顏色的矩形。void myDisplay(void)(glClear(GL_COLOR_BUFFER_BIT);glColor3f(0.0f, 1.0f, 1.0f);glRectf(-0.5f, -0.5f, 0.5f, 0.5f);glFlush();)注意:glColor系列函數(shù),在參數(shù)類型不同時,表示最大”顏色的值也不同。采用f和d做后綴的函數(shù),以1.0表示最大的使用。采用b做后綴的函數(shù),以127表示最大的使用。采用ub做后綴的函數(shù),以255表示最大的使
43、用。采用s做后綴的函數(shù),以32767表示最大的使用。采用us做后綴的函數(shù),以65535表示最大的使用。這些規(guī)則看似麻煩,但熟悉后實(shí)際使用中不會有什么障礙。2、索引顏色在索引顏色模式中,OpenGL需要一個顏色表。這個表就相當(dāng)于畫家的調(diào)色板:雖然可以調(diào)出很多種顏色, 但同時存在于調(diào)色板上的顏色種數(shù)將不會超過調(diào)色板的格數(shù)。試將顏色表的每一項想象成調(diào)色板上的一個 格子:它保存了一種顏色。在使用索引顏色模式畫圖時,我說 我把第i種顏色設(shè)置為某某”,其實(shí)就相當(dāng)于將調(diào)色板的第i格調(diào)為某某顏色。我需要第k種顏色來畫圖”,那么就用畫筆去蘸一下第k格調(diào)色板。顏色表的大小是很有限的,一般在2564096之間,且總
44、是2的整數(shù)次嘉。在使用索引顏色方式進(jìn)行繪圖時, 總是先設(shè)置顏色表,然后選擇顏色。選擇顏色使用gllndex*系列函數(shù)可以在顏色表中選擇顏色。其中最常用的可能是gllndexi ,它的參數(shù)是一個整形。void glIndexi(GLint c);是的,這的確很簡單。設(shè)置顏色表OpenGL并直接沒有提供設(shè)置顏色表的方法,因此設(shè)置顏色表需要使用操作系統(tǒng)的支持。我們所用的Windows和其他大多數(shù)圖形操作系統(tǒng)都具有這個功能,但所使用的函數(shù)卻不相同。正如我沒有講述如何自己寫代碼在 Windows下建立一個窗口,這里我也不會講述如何在Windows下設(shè)置顏色表。GLUT工具包提供了設(shè)置顏色表的函數(shù)glut
45、SetColor ,但我測試始終有問題?,F(xiàn)在為了讓大家體驗一下索引顏色,我向大家介紹另一個OpenGL工具包:aux。這個工具包是 VisualStudio自帶的,不必另外安裝,但它已經(jīng)過時,這里僅僅是體驗一下,大家不必深入。#include #include #include #pragma comment (lib, opengl32.lib)#pragma comment (lib, glaux.lib)#include const GLdouble Pi = 3.1415926536;void myDisplay(void)int i;for(i=0; i8; +i)auxSetOne
46、Color(i, (float)(i&0 x04), (float)(i&0 x02), (float)(i&0 x01);glShadeModel(GL_FLAT);glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_TRIANGLE_FAN);glVertex2f(0.0f, 0.0f);for(i=0; i=8; +i)glIndexi(i);glVertex2f(cos(i*Pi/4), sin(i*Pi/4);glEnd();glFlush();)int main(void)(auxInitDisplayMode(AUX_SINGLE|AUX_INDEX)
47、;auxInitPosition(0, 0, 400, 400);auxInitWindow(L);myDisplay();Sleep(10 * 1000);return 0;)其它部分大家都可以不管,只看 myDisplay函數(shù)就可以了。首先,使用auxSetOneC010r設(shè)置顏色表中的一格。循環(huán)八次就可以設(shè)置八格。glShadeModel等下再講,這里不提。然后在循環(huán)中用glVertex設(shè)置頂點(diǎn),同時用glIndexi改變頂點(diǎn)代表的顏色。最終得到的效果是八個相同形狀、不同顏色的三角形。索引顏色雖然講得多了點(diǎn)。索引顏色的主要優(yōu)勢是占用空間小(每個像素不必單獨(dú)保存自己的顏色,只用很少的二進(jìn)制
48、位就可以代表其顏色在顏色表中的位置),花費(fèi)系統(tǒng)資源少,圖形運(yùn)算速度快,但它編程稍稍顯得不是那么方便,并且畫面效果也會比 RGB顏色差一些。 星際爭霸”可能代表了 256色的顏色表的畫面 效果,雖然它在一臺很爛的 PC上也可以運(yùn)行很流暢,但以目前的眼光來看,其畫面效果就顯得不足了。目前的PC機(jī)性能已經(jīng)足夠在各種場合下使用RGB顏色,因此PC程序開發(fā)中,使用索引顏色已經(jīng)不是主流。當(dāng)然,一些小型設(shè)備例如GBA、手機(jī)等,索引顏色還是有它的用武之地。3、指定清除屏幕用的顏色我們寫:glClear(GL_COLOR_BUFFER_BIT);意思是把屏幕上的顏色清空。但實(shí)際上什么才叫空”呢?在宇宙中,黑色代
49、表了空”;在一張白紙上,白色代表了空”;在信封上,信封的顏色才是空”。OpenGL用下面的函數(shù)來定義清楚屏幕后屏幕所擁有的顏色。在RGB模式下,使用glClearC010r來指定空”的顏色,它需要四個參數(shù),其參數(shù)的意義跟glColor4f相似。在索引顏色模式下,使用 glClearIndex來指定空”的顏色所在的索引,它需要一個參數(shù),其意義跟 glIndexi 相似。void myDisplay(void)(glClearC010r(1.0f, 0.0f, 0.0f, 0.0f);glClear(GL_COLOR_BUFFER_BIT);glFlush();)4、指定著色模型OpenGL允許為
50、同一多邊形的不同頂點(diǎn)指定不同的顏色。例如:#include const GLdouble Pi = 3.1415926536;void myDisplay(void)int i;/ glShadeModel(GL_FLAT);glClear(GL_COLOR_BUFFER_BIT);glBegin(GL_TRIANGLE_FAN);glColor3f(1.0f, 1.0f, 1.0f);glVertex2f(0.0f, 0.0f);for(i=0; i=8; +i) (glColor3f(i&0 x04, i&0 x02, i&0 x01);glVertex2f(cos(i*Pi/4), si
51、n(i*Pi/4);glEnd();glFlush();在默認(rèn)情況下,OpenGL會計算兩點(diǎn)頂點(diǎn)之間的其它點(diǎn),并為它們填上 誓適”的顏色,使相鄰的點(diǎn)的顏色值都比較接近。如果使用的是RGB模式,看起來就具有漸變的效果。如果是使用顏色索引模式,則其相鄰點(diǎn)的索引值是接近的,如果將顏色表中接近的項設(shè)置成接近的顏色,則看起來也是漸變的效果。但如果顏色 表中接近的項顏色卻差距很大,則看起來可能是很奇怪的效果。使用glShadeModel函數(shù)可以關(guān)閉這種計算,如果頂點(diǎn)的顏色不同,則將頂點(diǎn)之間的其它點(diǎn)全部設(shè)置為與某一個點(diǎn)相同。(直線以后指定的點(diǎn)的顏色為準(zhǔn),而多邊形將以任意頂點(diǎn)的顏色為準(zhǔn),由實(shí)現(xiàn)決定。)為了避免
52、這個不確定性,盡量在多邊形中使用同一種顏色。glShadeModel的使用方法:glShadeModel(GL_SMOOTH); /平滑方式,這也是默認(rèn)方式glShadeModel(GL_FLAT); / 單色方式小結(jié):本課學(xué)習(xí)了如何設(shè)置顏色。其中RGB顏色方式是目前PC機(jī)上的常用方式??梢栽O(shè)置glClear清除后屏幕所剩的顏色??梢栽O(shè)置顏色填充方式:平滑方式或單色方式。2.4變換在前面繪制幾何圖形的時候,大家是否覺得我們繪圖的范圍太狹隘了呢?坐標(biāo)只能從 -1到1,還只能是X 軸向右,丫軸向上,z軸垂直屏幕。這些限制給我們的繪圖帶來了很多不便。我們生活在一個三維的世界一一如果要觀察一個物體,我
53、們可以:1、從不同的位置去觀察它。(視圖變換)2、移動或者旋轉(zhuǎn)它,當(dāng)然了,如果它只是計算機(jī)里面的物體,我們還可以放大或縮小它。(模型變換)3、如果把物體畫下來,我們可以選擇:是否需要一種近大遠(yuǎn)小”的透視效果。另外,我們可能只希望看到物體的一部分,而不是全部(剪裁)。(投影變換)4、我們可能希望把整個看到的圖形畫下來,但它只占據(jù)紙張的一部分,而不是全部。(視口變換)這些,都可以在OpenGL中實(shí)現(xiàn)。OpenGL變換實(shí)際上是通過矩陣乘法來實(shí)現(xiàn)。無論是移動、旋轉(zhuǎn)還是縮放大小,都是通過在當(dāng)前矩陣的基 礎(chǔ)上乘以一個新的矩陣來達(dá)到目的。關(guān)于矩陣的知識,這里不詳細(xì)介紹,有興趣的朋友可以看看線性代數(shù) (大學(xué)生
54、的話多半應(yīng)該學(xué)過的)。OpenGL可以在最底層直接操作矩陣,不過作為初學(xué),這樣做的意義并不大。這里就不做介紹了。 1、模型變換和視圖變換從相對移動”的觀點(diǎn)來看,改變觀察點(diǎn)的位置與方向和改變物體本身的位置與方向具有等效性。在OpenGL中,實(shí)現(xiàn)這兩種功能甚至使用的是同樣的函數(shù)。由于模型和視圖的變換都通過矩陣運(yùn)算來實(shí)現(xiàn),在進(jìn)行變換前,應(yīng)先設(shè)置當(dāng)前操作的矩陣為模型視圖矩陣”設(shè)置的方法是以GL_MODELVIEW為參數(shù)調(diào)用glMatrixMode函數(shù),像這樣: glMatrixMode(GL_MODELVIEW);通常,我們需要在進(jìn)行變換前把當(dāng)前矩陣設(shè)置為單位矩陣。這也只需要一行代碼: glLoadI
55、dentity();然后,就可以進(jìn)行模型變換和視圖變換了。進(jìn)行模型和視圖變換,主要涉及到三個函數(shù):glTranslate*,把當(dāng)前矩陣和一個表示移動物體的矩陣相乘。三個參數(shù)分別表示了在三個坐標(biāo)上的位移值。glRotate*,把當(dāng)前矩陣和一個表示旋轉(zhuǎn)物體的矩陣相乘。物體將繞著(0,0,0)到(x,y,z)的直線以逆時針旋轉(zhuǎn),參數(shù)angle表示旋轉(zhuǎn)的角度。glScale*,把當(dāng)前矩陣和一個表示縮放物體的矩陣相乘。x,y,z分別表示在該方向上的縮放比例。注意我都是說 與XX相乘”,而不是直接說 這個函數(shù)就是旋轉(zhuǎn)”或者這個函數(shù)就是移動”,這是有原因的, 馬上就會講到。假設(shè)當(dāng)前矩陣為單位矩陣,然后先乘以
56、一個表示旋轉(zhuǎn)的矩陣R,再乘以一個表示移動的矩陣T,最后得到的矩陣再乘上每一個頂點(diǎn)的坐標(biāo)矩陣v。所以,經(jīng)過變換得到的頂點(diǎn)坐標(biāo)就是 (RT)v)。由于矩陣乘法的結(jié)合率,(RT)v) = (R(Tv),換句話說,實(shí)際上是先進(jìn)行移動,然后進(jìn)行旋轉(zhuǎn)。即:實(shí)際變換的順序與代碼中寫的順序是相反的。由于先移動后旋轉(zhuǎn)”和先旋轉(zhuǎn)后移動”得到的結(jié)果很可能不同,初學(xué)的時候需要特別注意這一點(diǎn)。OpenGL之所以這樣設(shè)計,是為了得到更高的效率。但在繪制復(fù)雜的三維圖形時,如果每次都去考慮如何 把變換倒過來,也是很痛苦的事情。這里介紹另一種思路,可以讓代碼看起來更自然(寫出的代碼其實(shí)完 全一樣,只是考慮問題時用的方法不同了)
57、 。讓我們想象,坐標(biāo)并不是固定不變的。旋轉(zhuǎn)的時候,坐標(biāo)系統(tǒng)隨著物體旋轉(zhuǎn)。移動的時候,坐標(biāo)系統(tǒng)隨著物體移動。如此一來,就不需要考慮代碼的順序反轉(zhuǎn)的問題了。以上都是針對改變物體的位置和方向來介紹的。如果要改變觀察點(diǎn)的位置,除了配合使用glRotate*和glTranslate*函數(shù)以外,還可以使用這個函數(shù):gluLookAt。它的參數(shù)比較多,前三個參數(shù)表示了觀察點(diǎn)的位置,中間三個參數(shù)表示了觀察目標(biāo)的位置,最后三個參數(shù)代表從(0,0,0)到(x,y,z)的直線,它表示了觀察者認(rèn)為的士”方向。 2、投影變換 投影變換就是定義一個可視空間,可視空間以外的物體不會被繪制到屏幕上。(注意,從現(xiàn)在起,坐標(biāo)可以
58、不再是-1.0至ij 1.0 了!)OpenGL支持兩種類型的投影變換,即透視投影和正投影。投影也是使用矩陣來實(shí)現(xiàn)的。如果需要操作投 影矩陣,需要以 GL_PROJECTION為參數(shù)調(diào)用glMatrixMode函數(shù)。glMatrixMode(GL_PROJECTION);通常,我們需要在進(jìn)行變換前把當(dāng)前矩陣設(shè)置為單位矩陣。 glLoadIdentity();透視投影所產(chǎn)生的結(jié)果類似于照片,有近大遠(yuǎn)小的效果,比如在火車頭內(nèi)向前照一個鐵軌的照片,兩條鐵 軌似乎在遠(yuǎn)處相交了。使用glFrustum函數(shù)可以將當(dāng)前的可視空間設(shè)置為透視投影空間。其參數(shù)的意義如下圖:nearfar也可以使用更常用的 glu
59、Perspective函數(shù)。其參數(shù)的意義如下圖:tar正投影相當(dāng)于在無限遠(yuǎn)處觀察得到的結(jié)果,它只是一種理想狀態(tài)。但對于計算機(jī)來說,使用正投影有可能 獲得更好的運(yùn)行速度。使用glOrtho函數(shù)可以將當(dāng)前的可視空間設(shè)置為正投影空間。其參數(shù)的意義如下圖:如果繪制的圖形空間本身就是二維的,可以使用 gluOrtho2D。他的使用類似于glOrgho。3、視口變換當(dāng)一切工作已經(jīng)就緒,只需要把像素繪制到屏幕上了。這時候還剩最后一個問題:應(yīng)該把像素繪制到窗口的哪個區(qū)域呢?通常情況下,默認(rèn)是完整的填充整個窗口,但我們完全可以只填充一半。(即:把整個圖象填充到一半的窗口內(nèi))undist orWddistorto
60、d使用glViewport來定義視口。其中前兩個參數(shù)定義了視口的左下腳(0,0表示最左下方),后兩個參數(shù)分別是寬度和高度。4、操作矩陣堆棧介于是入門教程,先簡單介紹一下堆棧。你可以把堆棧想象成一疊盤子。開始的時候一個盤子也沒有,你 可以一個一個往上放,也可以一個一個取下來。每次取下的,都是最后一次被放上去的盤子。通常,在計 算機(jī)實(shí)現(xiàn)堆棧時,堆棧的容量是有限的,如果盤子過多,就會出錯。當(dāng)然,如果沒有盤子了,再要求取一 個盤子,也會出錯。我們在進(jìn)行矩陣操作時,有可能需要先保存某個矩陣,過一段時間再恢復(fù)它。當(dāng)我們需要保存時,調(diào)用 glPushMatrix函數(shù),它相當(dāng)于把矩陣(相當(dāng)于盤子)放到堆棧上。
溫馨提示
- 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
- 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯(lián)系上傳者。文件的所有權(quán)益歸上傳用戶所有。
- 3. 本站RAR壓縮包中若帶圖紙,網(wǎng)頁內(nèi)容里面會有圖紙預(yù)覽,若沒有圖紙預(yù)覽就沒有圖紙。
- 4. 未經(jīng)權(quán)益所有人同意不得將文件中的內(nèi)容挪作商業(yè)或盈利用途。
- 5. 人人文庫網(wǎng)僅提供信息存儲空間,僅對用戶上傳內(nèi)容的表現(xiàn)方式做保護(hù)處理,對用戶上傳分享的文檔內(nèi)容本身不做任何修改或編輯,并不能對任何下載內(nèi)容負(fù)責(zé)。
- 6. 下載文件中如有侵權(quán)或不適當(dāng)內(nèi)容,請與我們聯(lián)系,我們立即糾正。
- 7. 本站不保證下載資源的準(zhǔn)確性、安全性和完整性, 同時也不承擔(dān)用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。
最新文檔
- 銷售資產(chǎn)合同范本
- 墓碑雕刻合同范本
- Troriluzole-hydrochloride-BHV-4157-hydrochloride-生命科學(xué)試劑-MCE
- 單位合同范本6
- 1-3-Diarachidoyl-glycerol-生命科學(xué)試劑-MCE
- 基坑維護(hù)合同范本
- 科技在影視產(chǎn)業(yè)中的運(yùn)用與影響
- 電影制作與發(fā)布的商務(wù)流程和禮節(jié)解析
- 電子商務(wù)盈利策略全解析
- 現(xiàn)代辦公樓的綠建設(shè)計與實(shí)踐案例分析報告
- 2025年山東鋁業(yè)職業(yè)學(xué)院高職單招職業(yè)技能測試近5年常考版參考題庫含答案解析
- 2024年湖南汽車工程職業(yè)學(xué)院單招職業(yè)技能測試題庫標(biāo)準(zhǔn)卷
- (正式版)HGT 6313-2024 化工園區(qū)智慧化評價導(dǎo)則
- 二級公立醫(yī)院績效考核三級手術(shù)目錄(2020版)
- 高中化學(xué)競賽培訓(xùn)計劃
- 研發(fā)向善課程----綻放生命異彩
- 電廠機(jī)組深度調(diào)峰摸底試驗方案
- 地球上的大氣知識結(jié)構(gòu)圖
- 加油站數(shù)質(zhì)量管理考核辦法版.doc
- 華文版四年級下冊全冊書法教案
- 最新整理自動化儀表專業(yè)英語詞匯只是分享
評論
0/150
提交評論