計算機圖形學大作業報告_第1頁
計算機圖形學大作業報告_第2頁
計算機圖形學大作業報告_第3頁
計算機圖形學大作業報告_第4頁
計算機圖形學大作業報告_第5頁
已閱讀5頁,還剩35頁未讀 繼續免費閱讀

下載本文檔

版權說明:本文檔由用戶提供并上傳,收益歸屬內容提供方,若內容存在侵權,請進行舉報或認領

文檔簡介

陳博文圖形學期末報告PAGEPAGE1云南大學軟件學院期末課程報告FinalCourseReportSchoolofSoftware,YunnanUniversity個人成績序號學號姓名成績1學期:2009年秋季學期課程名稱: 計算機圖形學任課教師: 實踐題目: 創建旋轉體小組長: 聯系電話: 電子郵件: 2009-2010學年上學期計算機圖形學成績考核表年級:專業:軟件工程學號:姓名:本人所做工作:指標內容分值指標內涵及評估標準得分技術路線的可行程度10合理可行,具體且有創新合理可行,具體基本合理可行不夠合理或不夠具體程序或系統設計思路10程序或系統思路非常清晰、運行正確程序或系統思路基本清晰、運行正確程序或系統思路清晰、環境配置錯誤無法運行程序或系統思路不清晰,程序無法運行小組成員的工作量(每個人分別打分)15高出平均要求工作量的15%以上高出平均要求工作量達到平均要求工作量低于平均要求的工作量理論知識應用水平15用理論知識對程序設計方法、思路和代碼進行詳盡、準確地分析和總結用理論知識對程序設計方法、思路和代碼進行較準確地分析和總結理論知識應用一般理論知識差達到預期目標的程度10完全達到基本達到無法預見未能達到團隊合作精神10很強的團隊合作精神合作情況良好合作情況一般合作不好,各自為政報告撰寫質量(30分)5報告非常完整報告比較完整完整程度一般報告不完整5邏輯結構清晰邏輯組織較好邏輯組織一般邏輯不清5內容非常豐富內容較豐富內容一般內容欠缺5文字表達非常好文字表達較好文字表達一般文字表達差,意思不明了5圖表制作非常專業化圖件制作良好圖件制作一般圖件制作效果差5整體效果很好整體效果良好整體效果一般整體效果差綜合得分(滿分100分)評語創建旋轉體總結報告(GB8567——88)1引言 51.1編寫目的 51.2背景 51.3定義 51.4參考資料 62實際開發結果 72.1產品 72.2主要功能和性能 72.3基本流程 102.4進度 202.5費用 203開發工作評價 223.1對生產效率的評價 223.2對產品質量的評價 223.3對技術方法的評價 223.4出錯原因的分析 224經驗與教訓 235附錄 261.引言1.1.編寫目的本學期計算機圖形學課程期末大作業二人小組主要的開發項目就是基于OpenGL的旋轉體實現,實現語言VC++,編輯、調試環境VS2008,在學期末終于基本開發完成。是對自我工作的檢驗和測試,在撰寫報告的過程中能夠更深刻的了解計算機圖形學的理念通過這份文檔來記錄我們在開發此軟件的過程中遇到的問題以及改善的方法。現在對整個開發過程加以認識、記錄和總結,留下經驗,汲取教訓。為以后的其他工作留下經驗資料,為以后遇到相同的問題和從事類似項目奠定堅實的基礎,以便以后有資可尋、有底可查,增長個人見識,為自己程序開發方面的成長而努力奮斗。并作為期末向指導老師報告的材料。通過此次大作業的編寫,我要達到進一步熟悉OpenGL編程的目的,并在以后的學習中得到總結。1.2背景計算機圖形學(ComputerGraphics,簡稱CG)是一種使用數學算法將二維或三維圖形轉化為計算機顯示器的柵格形式的科學。簡單地說,計算機圖形學的主要研究內容就是研究如何在計算機中表示圖形、以及利用計算機進行圖形的計算、處理和顯示的相關原理與算法。圖形通常由點、線、面、體等幾何元素和灰度、色彩、線型、線寬等非幾何屬性組成。從處理技術上來看,圖形主要分為兩類,一類是基于線條信息表示的,如工程圖、等高線地圖、曲面的線框圖等,另一類是明暗圖,也就是通常所說的真實感圖形。計算機圖形學一個主要的目的就是要利用計算機產生令人賞心悅目的真實感圖形。為此,必須建立圖形所描述的場景的幾何表示,再用某種光照模型,計算在假想的光源、紋理、材質屬性下的光照明效果。所以計算機圖形學與另一門學科計算機輔助幾何設計有著密切的關系。事實上,圖形學也把可以表示幾何場景的曲線曲面造型技術和實體造型技術作為其主要的研究內容。同時,真實感圖形計算的結果是以數字圖像的方式提供的,計算機圖形學也就和圖像處理有著密切的關系。圖形與圖像兩個概念間的區別越來越模糊,但還是有區別的:圖像純指計算機內以位圖形式存在的灰度信息,而圖形含有幾何屬性,或者說更強調場景的幾何表示,是由場景的幾何模型和景物的物理屬性共同組成的。計算機圖形學的研究內容非常廣泛,如圖形硬件、圖形標準、圖形交互技術、光柵圖形生成算法、曲線曲面造型、實體造型、真實感圖形計算與顯示算法、非真實感繪制,以及科學計算可視化、計算機動畫、自然景物仿真、虛擬現實等OpenGL是個與硬件無關的軟件接口,可以在不同的平臺如Windows95、WindowsNT、Unix、Linux、MacOS、OS/2之間進行移植。因此,支持OpenGL的軟件具有很好的移植性,可以獲得非常廣泛的應用。由于OpenGL是圖形的底層圖形庫,沒有提供幾何實體圖元,不能直接用以描述場景。但是,通過一些轉換程序,可以很方便地將AutoCAD、3DS/3DSMAX等3D圖形設計軟件制作的DXF和3DS模型文件轉換成OpenGL的頂點數組計算機圖形學(ComputerGraphics)是近三十年來發展迅速,應用廣泛的新興學科,主要研究怎樣用數字計算機生成、處理和顯示圖形。

圖形的具體應用范圍很廣,但是從基本的處理技術看只有兩類,一類是線條,如工程圖、地圖、曲線圖表等;另一類是明暗圖,與照片相似。為了生成圖形,首先要有原始數據或數學模型,如工程人員構思的草圖,地形航測的判讀數據,飛機的總體方案模型,企業經營的月統計資料等等。這些數字化的輸入經過計算機處理后變成圖形輸出。可以說計算機圖形學在當代社會的運用已經涉及到了各個領域上的運用,無論在什么領域上計算機圖形學都發揮到了自己的作用;計算機圖形學以其對圖像的專業處理技術,對圖形圖像的加工運用,實現圖形的立體轉化,三維立體圖形的旋轉變形,由平面圖到三維立體圖的轉化等等,都是命了計算機圖形學強大的圖像處理技術。

說明:a.本項目的名稱為“計算機圖形學期末大作業”,開發出來的項目名稱為“旋轉體功能圖”。b.此軟件為2009年秋季學期云南大學軟件學院計算機圖形學期末大作業最終報告,編寫者為原飛、陳博文。1.3定義計算機圖形學:計算機圖形學的研究內容非常廣泛,如圖形硬件、圖形標準、圖形交互技術、光柵圖形生成算法、曲線曲面造型、實體造型、真實感圖形計算與顯示算法、非真實感繪制,以及計算機動畫、自然景物仿真、虛擬現實等。OpenGl:用于編寫計算機圖形學的程序的編譯工具。OpenGL是行業領域中最為廣泛接納的2D/3D圖形API,其自誕生至今已催生了各種計算機平臺及設備上的數千優秀應用程序。OpenGL是獨立于視窗操作系統或其它操作系統的,亦是網絡透明的。在包含CAD、內容創作、能源、娛樂、游戲開發、制造業、制藥業及虛擬現實等行業領域中,OpenGL?幫助程序員實現在PC、工作站、超級計算機等硬件設備上的高性能、極具沖擊力的高視覺表現力圖形處理軟件的開發。OPENGL的功能及特點:OpenGL是一個開放的三維圖形軟件包,它獨立于窗口系統和操作系統,以它為基礎開發的應用程序可以十分方便地在各種平臺間移植;OpenGL可以與VisualC++緊密接口,便于實現機械手的有關計算和圖形算法,可保證算法的正確性和可靠性;OpenGL使用簡便,效率高。它具有七大功能:旋轉體:一條平面曲線繞著它所在的平面內的一條定直線旋轉所形成的曲面叫作旋轉面;封閉的旋轉面圍成的幾何體。旋轉矩陣:在乘以一個向量的時候有改變向量的方向但不改變大小的效果的矩陣。旋轉矩陣不包括反演,它可以把右手坐標系改變成左手坐標系或反之。所有旋轉加上反演形成了正交矩陣的集合。旋轉變換:簡稱旋轉.歐氏幾何中的一種重要變換.即在歐氏平面上(歐氏空間中),讓每一點P繞一固定點(固定軸線)旋轉一個定角,變成另一點P′,如此產生的變換稱為平面上(空間中)的旋轉變換.。變換矩陣:在線性代數中,線性變換能夠用矩陣表示。如果T是一個把R映射到R的線性變換,且x是一個具有n個元素的列向量,,那么我們把m×n的矩陣A,稱為T的變換矩陣。3D坐標系:

三維笛卡兒坐標系是在二維笛卡兒坐標系的基礎上根據右手\o"Zgirls_1@utops.cc"定則增加第三維坐標(即Z軸)而形成的。2D坐標系:在同一個平面上互相垂直且有公共原點的兩條數軸構成平面直角坐標系。1.4參考資料a.計算機圖形學,項志鋼,清華大學出版社,第1版,2006年12月;b.軟件文檔國家標準(GB8567-88);c.屬于本項目的其他已發表的文件;d.OpenGL編程手冊;e.VC++編程手冊;2實際開發結果2.1產品1

系統需求分析一個旋轉體由其外輪廓線繞其豎直中心軸旋轉而成。程序要求建立一個窗口顯示豎直的中心軸,并且要求實現輪廓線的編輯,具體包含功能:節點的增加、刪除和節點間自動連線。程序要求建立另外一個窗口顯示輪廓線繞中心軸旋轉以后的三維物體,本窗口還要求實現三維物體的Phong著色和對三維物體的簡單操作,具體包含:放大、縮小和旋轉。移動光源紋理映射效果霧化效果輪廓線使用樣條技術2總體設計1項目規劃:本系統是一個基于OpenGL開發的實現能夠進行人機交互的繪制3D旋轉體的系統,本系統中的功能模塊主要分為以下幾種:矩陣運算模塊:實現兩個或多個矩陣的相關運算,為繪制圖形提供數據結構,體現圖形轉化過程中的算法。顯示圖形模塊:用于設定圖像的顯示方式,繪制方法,在其中還可以設置光源位置等相關的顯示信息。鍵盤敲擊模塊:對不同的鍵盤敲擊事件作出相應的處理,包括點線的轉化,霧化效果等。鼠標點擊模塊:在3D顯示窗口添加的鼠標事件,對鼠標的事件作出相應的響應效果。動作模塊:根據左邊用戶繪制的2D圖形,動態的劃出右面相對應的3D圖像。找點模塊:在左邊的用戶畫圖窗口進行鎖定鼠標點擊時靠近的點。2系統功能結構3設計目標本系統是根據課本中的程序而開發的,基本能夠實現需求中所要求的功能,通過本系統可以達到以下目標:1系統運行穩定,安全可靠。2界面美觀、友好。3用戶操作使用方便。4生成的3D圖形效果良好。5能夠正確的生成用戶所要繪制的3D圖形3主要功能模塊設計1矩陣運算模塊的設計:功能描述:程序啟動后,這部分功能模塊會為整個應用程序提供算法支持,具體是矩陣直接的相互運算,在2D向3D轉化過程中會起到很重要的作用。代碼設計:floatvv(float*v1,float*v2){ returnv1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];}voidvxv(float*n,float*v1,float*v2){ n[0]=v1[1]*v2[2]-v1[2]*v2[1];n[1]=v1[2]*v2[0]-v1[0]*v2[2]; n[2]=v1[0]*v2[1]-v1[1]*v2[0];}voidloadIdentity(Matrixm){ Matrixidentity={{1.0,0.0,0.0,0.0}, {0.0,1.0,0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; for(inti=0;i<4;i++) for(intj=0;j<4;j++) m[i][j]=identity[i][j];}voidpreMultiply(Matrixp,Matrixm){ inti,j; Matrixt; for(i=0;i<4;i++) for(j=0;j<4;j++) t[i][j]=p[i][0]*m[0][j]+p[i][1]*m[1][j]+p[i][2]*m[2][j]+p[i][3]*m[3][j]; for(i=0;i<4;i++) for(j=0;j<4;j++) m[i][j]=t[i][j];}2顯示圖形模塊的設計:功能描述:該模塊主要為所要畫的圖形進行描述,是繪制圖形的主要函數,通過調用這個功能模塊就能畫出用于顯示給用戶的圖形。代碼設計://2D圖形的display函數voiddisplay(){ glClear(GL_COLOR_BUFFER_BIT); if(n==1&&type==GL_LINE_STRIP){ glBegin(GL_POINTS); glVertex2iv(vert[0]); glColor3f(0,0.5,0.5); glVertex2i(width-vert[0][0]-1,vert[0][1]); glEnd();} glColor3f(0,0.5,0.5); glBegin(GL_LINES); glVertex2i(width/2,0); glVertex2i(width/2,height-1); glEnd(); glBegin(type); for(inti=0;i<n;i++)glVertex2i(width-vert[i][0]-1,vert[i][1]); glEnd(); glColor3f(1,1,0);glBegin(type); for(inti=0;i<n;i++)glVertex2iv(vert[i]); glEnd(); glutSwapBuffers(); initQMesh(); glutSetWindow(winid); glutPostRedisplay();}//3D圖形的顯示函數voidmodelDisplay(){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); floatM[16]; for(intr=0;r<4;r++)for(intc=0;c<4;c++)M[4*c+r]=CRM[r][c]; glMultMatrixf(M); glScalef(zoom,zoom,zoom); drawQMesh(); glPopMatrix(); glPushMatrix();glLightfv(GL_LIGHT0,GL_AMBIENT,amb); glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);glPopMatrix(); glutSwapBuffers();}3鍵盤敲擊模塊功能描述:該功能主要為兩個窗體添加鍵盤敲擊事件,在2D窗體中主要添加了反走樣效果,清除所畫的圖,點線轉化功能,對于3D窗體主要添加了投影方式的變換,霧化效果,光源移動的功能代碼設計://2D繪制窗體的鍵盤敲擊處理函數voidkeyboard(unsignedcharkey,intx,inty){ switch(key){ case'a':antialiasing=!antialiasing;//反走樣效果 if(antialiasing){ glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); }else{ glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); } break; case'c':n=0;break;//清除界面功能 case'l':type=GL_LINE_STRIP;break;//繪制線功能 case'v':type=GL_POINTS;break;//繪制點功能 } glutPostRedisplay();}//3D顯示窗體的鍵盤敲擊事件處理函數:voidmodelKeyboard(unsignedcharkey,intx,inty){ switch(key){ case'o':glMatrixMode(GL_PROJECTION);//正投影 glLoadIdentity(); glOrtho(-4,4,-4,4,6,14); glMatrixMode(GL_MODELVIEW); break; case'p':glMatrixMode(GL_PROJECTION);//側投影,不過是默認的 glLoadIdentity(); gluPerspective(45.0,1.0,6.0,14.0); glMatrixMode(GL_MODELVIEW); break; case'm':lightPosition[0]=lightPosition[0]-0.5; //光源移動 break; case'n':lightPosition[1]=lightPosition[1]-0.5; break; case'z':lightPosition[2]=lightPosition[2]-0.5; break; case'q':glEnable(GL_FOG);//霧化效果 { glFogi(GL_FOG_MODE,GL_LINEAR); GLfloatfogColor[]={1.9,1.1,2.2,0.5}; glFogfv(GL_FOG_COLOR,fogColor); glFogf(GL_FOG_START,3.0); glFogf(GL_FOG_END,15.0); glHint(GL_FOG_HINT,GL_DONT_CARE); } break; case'k':glDisable(GL_FOG); break; } glutPostRedisplay();}4鼠標點擊模塊功能描述:該功能模塊主要實現了對兩個窗體鼠標事件的處理,對于3D窗體實現了鼠標左鍵旋轉,由鍵放大縮小的效果,2D窗體實現了左鍵畫點,右鍵可以對已經存在的點改變它的位置。代碼設計://3D窗體的鼠標事件voidmodelMouse(intbutton,intstate,intx,inty){ switch(button){ caseGLUT_LEFT_BUTTON: if(state==GLUT_DOWN){ cx=x; cy=h-1-y; dx=dy=0; left_button_down=true; }else left_button_down=false; break; caseGLUT_RIGHT_BUTTON: if(state==GLUT_DOWN){ cx=x; cy=h-1-y; right_button_down=true; }else right_button_down=false; break; }}//2D窗體鼠標事件voidmouse(intbutton,intstate,intx,inty){ y=height-1-y; switch(button){ caseGLUT_LEFT_BUTTON: if(state==GLUT_DOWN&&!rubberbanding){ v=n++; vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; vert[v][1]=(y<0)?0:(y>=height)?height-1:y; rubberbanding=true; glutPostRedisplay(); } elserubberbanding=false; break; caseGLUT_RIGHT_BUTTON: if(state==GLUT_DOWN&&!rubberbanding&&(v=findVertex(x,y))!=-1){ if(glutGetModifiers()==GLUT_ACTIVE_CTRL){ for(inti=v;i<n-1;i++){vert[v][0]=vert[i+1][0]; vert[i][1]=vert[i+1][1]; } n--; }else{ vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; vert[v][1]=(y<0)?0:(y>=height)?height-1:y; rubberbanding=true; } glutPostRedisplay(); } elserubberbanding=false; break; }}5找點模塊功能描述:此方法主要用于對用戶所需要的點進行鎖定。能夠改變原來已經存在的點。intfindVertex(intx,inty){//鎖定鼠標靠近的點 intdx,dy; for(inti=0;i<n;i++){ dx=vert[i][0]-x; dy=vert[i][1]-y; if(dx*dx+dy*dy<16)returni; } return-1;}2.2主要功能和性能逐項列出本軟件產品所實際具有的主要功能和性能,對照可行性研究報告、項目開發計劃、功能需求說明書的有關內容,說明原定的開發目標是達到了、未完全達到、或超過了。通過Editpolygons窗口(二維多邊形編輯視窗)繪制多邊形。對繪制出的多邊形能增刪頂點改變多邊形形狀。通過Objectwindow:李文云,向明海窗口(三維旋轉體顯示視窗)顯示在二維多邊形編輯視窗中編輯好的旋轉體輪廓的三維旋轉體映射。在三維旋轉體顯示視窗中通過o鍵切換到正投影顯示,通過p鍵切換到透視投影投影顯示在三維旋轉體顯示視窗中:通過小寫字母x用于對電光源位置的x坐標做減量操作,大寫字母X用于對電光源位置的x坐標做增量操作;小寫字母y用于對電光源位置的x坐標做減量操作,大寫字母Y用于對電光源位置的y坐標做增量操作;小寫字母z用于對電光源位置的z坐標做減量操作,大寫字母Z用于對電光源位置的z坐標做增量操作;字母f、F用于開啟霧化效果,小寫字母n用于關閉霧化效果在三維旋轉體顯示視窗中,通過按下鼠標右鍵同時移動光標來改變三維旋轉體大小在三維旋轉體顯示視窗中,通過按下鼠標左鍵同時移動光標來轉動三維旋轉體。說明:原定的開發目標達到了。所要求的全部實現附加要求實現了移動光源,霧化效果兩項。功能截圖:同時本程序還實現了在編輯基礎圖形窗口的反走樣效果,使用鍵盤的“a”鍵進行控制,當按下“a”鍵時將出現以下的效果

本程序還實現了按下“c”將編輯窗口中的所有圖形清除本程序實現了只顯示點來作為基礎圖形的輪廓,通過按下鍵盤的“v”鍵可以實現這一功能。如果希望恢復原本的使用線來畫出圖形的效果的話可以通過按下鍵盤的“L”鍵來進行控制,這樣就會恢復為默認的情況了在3D圖形顯示框中實現了對旋轉體的Phong著色,旋轉體的基本放大,縮小,旋轉等操作在圖形框中使用鼠標左鍵按下之后進行拖動,就可以對旋轉體進行旋轉的控制在3D圖形顯示框中實現了對旋轉體的Phong著色,旋轉體的基本放大,縮小,旋轉等操作在圖形框中使用鼠標左鍵按下之后進行拖動,就可以對旋轉體進行旋轉的控制使用鼠標控制旋轉之后在圖形框中使用鼠標右鍵按下之后拖動就可以控制旋轉體進行縮放下圖是縮小之后的圖形下圖是放大之后的圖形關閉霧化效果移動光源刪除頂點:本程序同樣實現了光源的移動按下“x”之后可以進行光源坐標1的負相移動,按下“y”之后可以實現光源坐標2的負相移動,按下“z”之后可以實現光源坐標3的負相移動,按下“1”之后可以實現光源坐標1的正相移動,按下“2”之后可以實現光源坐標2的正相移動,按下“3”之后可以實現光源坐標3的正相移動。2.3基本流程這個程序使用VS為編譯工具,使用C++語言,運用OPENGL技術,使窗口能夠動態的接收用戶的輸入信息,包括鼠標和鍵盤的事件響應,使用戶能夠畫出自己想要的對稱二維圖形,再由程序將其轉換為三維圖像,并最終實現三維圖像的各種操縱功能,具體實現是一個一個窗體進行實現的Editpolygons窗體的實現:首先,繪制基本窗體,包括左邊,色調等內容接著,繪制中軸線及相關的內容接著,在窗體中加入鍵盤和鼠標的事件截獲功能,使其能捕獲鼠標或鍵盤的事件接著,制作點繪制線的功能,將線繪制成幾何圖形。接著,利用中軸線使線的坐標關于中軸對稱,使其成為對稱圖形接著,添加反走樣效果,添加清楚界面功能,添加繪制線和繪制點的功能。DisplayObject窗口的實現首先,繪制基本窗體,包括左邊,色調等內容接著,通過第一個窗體的內容繪制三維圖形接著,實現其視角的轉移接著,增加其視角縮進效果最后,增加其霧化效果,光源移動效果通過二維制圖視窗(程序中為Editpolygons)用戶可以以交互的方式描繪與修改旋轉體的輪廓二維多邊形。多邊形在程序中由一個名為vert的數組代表,它的元素為頂點坐標(x,y)。器顯示的形式可以是一系列的點,一條折現或一條閉合折線。繪制多邊形:通過交互用戶可以增加,刪除或改變頂點位置進而給代表旋轉體的多邊形帶來相應網格的變化。當鼠標光標在Editpolygons視窗中時,不按下鼠標鍵,光標移動將不會產生任何影響。當按下左鍵時,就會在現存頂點序列后面加上一個當前光標位置的頂點。如果這個新頂點是第一個頂點,則他就以點的形式出現。否則這個頂點就以線段的形式與前一個頂點相連。在左鍵保持被保持被按下狀態時的任何光標移動都經過橡皮圈技術處理。釋放左鍵,新頂點與光標脫離。用戶可以把光標移動到一個現存頂點的重力場之內,并壓下鼠標右鍵鍵就可以選中該頂點。如果選中成功,就可以在保持右鍵被壓下的狀態下,改變頂點位置(使用橡皮圈技術),如果選擇失敗,則不會對圖形產生影響。函數為:intfindVertex(intx,inty){如果在Ctrl建被按下的狀態下選擇點成功的話,可以刪除該頂點。函數為:voidmouse(intbutton,intstate,intx,inty)繪制三維旋轉體:在鍵盤事件處理子程序voidkeyboard(unsignedcharkey,intx,inty)中定義了幾個單字指令鍵:a用于啟動和終止反走樣功能;c,C用于清除顯示區域,就是刪除所有頂點;l,L以線條的方式顯示多邊形;v,V僅顯示頂點display子函數在多邊形繪制視窗正中間畫出一條垂直線來作為旋轉軸位置的位置視覺指南:glBegin(GL_LINES);//繪制中間分界線。另外還畫出當前輪廓線相對于旋轉軸的鏡面反射來突出正在繪制中的物體的完整外形: initQMesh();。最后創建與低昂前輪廓相對應的三位模型,并刷新顯示視窗:glutSetWindow(winid);//顯示三位物體顯示窗口;glutPostRedisplay();。回調子程序motion函數跟蹤鼠標按鈕被按下時的光標位置,在這對頂點以橡皮圈方式附屬于于光標的有效范圍作了限制,這樣每個頂點都不會離開繪制視窗的有半側:voidmotion(intx,inty){ if(rubberbanding){//如果橡皮圈打開,更新頂點vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x;//頂點被用新的索引標記 y=height-1-y;vert[v][1]=(y<0)?0:(y>=height)?height-1:y;//光標位置glutPostRedisplay();//重畫頂點同樣在回調子程序mouse中也限制了新定點的初始位置以及現存頂點與繪圖光標的起始附屬關系,使得所有頂點在任何時刻都停留在繪圖視窗的右半側。有五個函數用來建立三位模型,實現著色,處理用戶與顯示視窗的交互活動旋轉體的表面有存放在數組QMesh中的一個四邊形網格代表,表面的前后兩面被賦予了不同顏色特征,現場有一個位于物體與觀察點之間,大約在十到十一點鐘的點光源。在main函數中,在glutMainLoop之前,下列代碼用于對顯示窗進行初始化,比設置有關材料,光照,投影和觀察的參數,以及把單位矩陣放入RM和CRM:2.4進度原計劃:十七周搞清基本原理,十八周完實現及完成全部代碼。實際進度:十八周完才搞清基本原理,十九周四才實現全部代碼。實際進度延遲了。延遲原因:總體上來講這學期選課太多,且有五門都有實驗和大作業,負擔太重,很是力不從心。大一沒好好學,數學基礎太差,很多東西理解起來十分困難。對課程基礎知識掌握不好,也造成相當大的困難。項目的實際總體進度是延遲了,在做需求分析時,我們基本按照提到的的要求進行了需求分析,其中做的比較完善的部分是第一個窗體的部分,可是由于技術問題,需求分析并沒有真正達到指導的目的,所以我們便開始代碼開發部分。由于對Opengl的運用并不十分熟練,使我們延長了較長時間,前一部分時間我們是在進行了對技術的基本學習和掌握,而在實際開發的過程中也是一個邊學習邊實踐的過程,也就造成了一些不必要的錯誤,而在開發過程中也遇到了許多預期之外的問題和困難,也有一些比較難解決的困難,并且由于C++的原因,調試起來比較不方便,而我們本身對代碼并不十分熟悉,所以總體上我們的開發時間使用了較長的時間。而測試文檔本打算比較快速的完成,但是卻發現在測試時候發現比較多的程序問題,使我們的測試進度受到影響,基本是邊改邊進行繼續測試整體來說工程進度拖后了不少,但是最終實現了。總的來說是由于之前對項目難度的估計不足和對自身實力的不明確造成的。但是我們在一步一步開發的過程中,漸漸掌握了技術的要點,使整個項目并沒有停滯下來,問題漸漸比較快速的解決完成。使我們收獲很多3開發工作評價3.3對技術方法的評價在開發的過程中,我們是由淺到深的進行開發,我們先爭取實現基本功能,之后再進一步實現擴展功能。具體來說,我們首先編寫我們已經掌握到了的知識,例如窗體的創建,窗體的基本功能,然后再添加一些通過查閱資料得到的知識要點,例如對稱圖形的繪制,鍵盤和鼠標的事件觸發問題,點和線的圖形分別繪制。之后再添加核心的功能,例如獲得點的矩陣,通過旋轉實現最終的三維圖形。最后再增加擴展功能,例如通過查閱資料和咨詢實現的霧化效果和光源效果等內容。在整體調試時,出現了很多問題,甚至使程序不能運行的問題,所以這也是我們遇到的最大障礙。而主要的所有困難來源是對于C++語言和OpenGL的不夠熟悉和一些錯誤的認識,由于開發過程比較底層,我們幾乎是一邊熟悉編譯環境,熟悉C++,熟悉OpenGL,一邊進行的項目,這使我們走了不少彎路,但是也從中獲得了很多的知識。但是無論之前怎樣,最終實現了基本功能就是一種成功,同時也實現了部分附加功能,尤其是這部分,我們投入了比較大的精力去研究和實現,所以,這就比較鍛煉我們的能力。這次大作業我們投入了較大的心血,所以對自己比較滿意,同時也體現了團隊的精神,互相合作和分工,使我們的項目能夠順利完成,最后也是對我們自己的一種肯定3.4出錯原因的分析本次大作業通過OPENGL制作的,由于之前對于OPENGL并不十分了解,也對C++并不十分了解,所以,我們在寫程序的過程中遇到了很多不應該有的低級錯誤,由于動手過程并不十分多,所以,我們對于錯誤的修改也并不十分在行,所以致使我們遇到了很多錯誤。同時,我們對于圖形學的理解也并不十分透徹,有些地方由于理解性錯誤和習慣思維,致使我們走了比較多彎路。4經驗與教訓個人小結陳博文學號20071120118通過對本次大作業報告的重新編寫,對本次大作業有了更加深入的理解,更進一步了解了OpenGL的用法,從計算機圖形學課程中可能收獲最多的并不是圖形學的一些基礎知識,雖然這些很重要,但是真正有些成就感的還是用OpenGL開發出來的這些程序。特別是這個項目,和前面幾個只需抄抄代碼就能出來的實驗相比,是需要好好動動腦筋的。在這個項目中需要處理鼠標等設備的輸入,然后再根據輸入捕捉相應的變化再進行處理。這一塊對于我來說是比較困難的。在解決這個問題上花了不少的時間,在解決這個問題之后應當說后面的工作還是比較輕松的。計算機圖形學是交互式圖形開發的基本理論,同時也是一門實踐性的學科,我通過做老師布置的4個試驗后,真正體會了下使用OpenGL編程,感覺OpenGL對底層的封裝很好,自己原本來認為會很復雜的東西,使用OpenGL幾行代碼就解決了,我覺得要學好OpenGL就要對它的API有足夠的了解,很多時候就是因為一個函數想不起來而花費大量的時間去網上搜尋結果,所以對一些常用的函數還是要牢記的。本項目實現的代碼結構還是非常簡單。但編程的時候遇到的一個比較大的問題是起初對于坐標系及在3D坐標系中向量的變換。由于我們主要從設備那只能獲得相對于屏幕的x-y坐標系的值,所以要經過一系列的轉換才能獲得重新獲得渲染3D圖像的一些值。整了很久才弄懂了這個過程,所以在此記錄下來。 控制物體的大小是通過鼠標檢測左右鼠標的按下狀態來控制的。而物體的旋轉則是通過跟蹤鼠標在窗體里的移動來實現的。用上一次保存的光標位置和現在通過檢測得到的位置可以算出當前的旋轉軸,兩點和這根旋轉軸可以確定兩個點之間的距離。通過連個計算公式就可以確定2D坐標和3D坐標的聯系。從而實現2D坐標系的變換和與之相應的3D坐標的變換。總之通過這學期的圖形學的學習,為以后有機會接觸圖形學相關知識打下了一定的基礎,同時也激發了自己對圖形學的興趣,我想如果以后有機會我會更加深入的去學習有關計算機圖形學的知識。至于OpenGL,還是比較底層,我想繼續在這學期的基礎上,再學些比較高層次的框架。

附錄:完整代碼#include<gl/glut.h>#include<math.h>#defineQMeshSize256intwidth=400,height=600,vert[100][2],n=0,type=GL_LINE_STRIP,v;boolrubberbanding=false,antialiasing=false;floatQMesh[100][QMeshSize+1][3];GLfloatlightPosition[]={-4.0,4.0,-6.0,1.0};GLfloatamb[]={0.3f,0.3f,0.3f,0.3f};GLfloatfrontDiffAmb[]={0.95f,0.3f,0.1f,1.0};GLfloatbackDiffAmb[]={0.1f,0.3f,0.95f,1.0};GLfloatSpec[]={0.45f,0.45f,0.45f,1.0};GLfloatSpecExp=15.0;boolleft_button_down=false,right_button_down=false;intw=600,h=600,winid,cx,cy,dx=0,dy=0;floatzoom=1.0;typedeffloatMatrix[4][4];MatrixRM,CRM;voidinitQMesh(){ floatr; for(inti=0;i<n;i++){ r=vert[i][0]-width/2.0; for(intj=0;j<QMeshSize;j++){ QMesh[i][j][0]=r*cos(3.14159*2*j/QMeshSize)/100; QMesh[i][j][1]=(vert[i][1]-height/2.0)/100; QMesh[i][j][2]=r*sin(3.14159*2*j/QMeshSize)/100; } QMesh[i][QMeshSize][0]=QMesh[i][0][0];QMesh[i][QMeshSize][1]=QMesh[i][0][1]; QMesh[i][QMeshSize][2]=QMesh[i][0][2]; }}voiddisplay(){ glClear(GL_COLOR_BUFFER_BIT); if(n==1&&type==GL_LINE_STRIP){ glBegin(GL_POINTS); glVertex2iv(vert[0]); glColor3f(0,0.5,0.5); glVertex2i(width-vert[0][0]-1,vert[0][1]); glEnd();} glColor3f(0,0.5,0.5); glBegin(GL_LINES); glVertex2i(width/2,0); glVertex2i(width/2,height-1); glEnd(); glBegin(type); for(inti=0;i<n;i++)glVertex2i(width-vert[i][0]-1,vert[i][1]); glEnd(); glColor3f(1,1,0);glBegin(type); for(inti=0;i<n;i++)glVertex2iv(vert[i]); glEnd(); glutSwapBuffers(); initQMesh(); glutSetWindow(winid); glutPostRedisplay();}voidkeyboard(unsignedcharkey,intx,inty){ switch(key){ case'a':antialiasing=!antialiasing; if(antialiasing){ glEnable(GL_BLEND); glEnable(GL_LINE_SMOOTH); }else{ glDisable(GL_BLEND); glDisable(GL_LINE_SMOOTH); } break; case'c':n=0;break; case'l':type=GL_LINE_STRIP;break; case'v':type=GL_POINTS;break; } glutPostRedisplay();}intfindVertex(intx,inty){ intdx,dy; for(inti=0;i<n;i++){ dx=vert[i][0]-x; dy=vert[i][1]-y; if(dx*dx+dy*dy<16)returni; } return-1;}voidmouse(intbutton,intstate,intx,inty){ y=height-1-y; switch(button){ caseGLUT_LEFT_BUTTON: if(state==GLUT_DOWN&&!rubberbanding){ v=n++; vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; vert[v][1]=(y<0)?0:(y>=height)?height-1:y; rubberbanding=true; glutPostRedisplay(); } elserubberbanding=false; break; caseGLUT_RIGHT_BUTTON: if(state==GLUT_DOWN&&!rubberbanding&&(v=findVertex(x,y))!=-1){ if(glutGetModifiers()==GLUT_ACTIVE_CTRL){ for(inti=v;i<n-1;i++){vert[v][0]=vert[i+1][0]; vert[i][1]=vert[i+1][1]; } n--; }else{ vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; vert[v][1]=(y<0)?0:(y>=height)?height-1:y; rubberbanding=true; } glutPostRedisplay(); } elserubberbanding=false; break; }}voidmotion(intx,inty){ if(rubberbanding){vert[v][0]=(x<width/2)?width/2:(x>=width)?width-1:x; y=height-1-y;vert[v][1]=(y<0)?0:(y>=height)?height-1:y;glutPostRedisplay(); }}voidnormalize(float*v){ floatm=sqrt(v[0]*v[0]+v[1]*v[1]+v[2]*v[2]); for(inti=0;i<3;i++) v[i]=v[i]/m;}floatvv(float*v1,float*v2){ returnv1[0]*v2[0]+v1[1]*v2[1]+v1[2]*v2[2];}voidvxv(float*n,float*v1,float*v2){ n[0]=v1[1]*v2[2]-v1[2]*v2[1];n[1]=v1[2]*v2[0]-v1[0]*v2[2]; n[2]=v1[0]*v2[1]-v1[1]*v2[0];}voidloadIdentity(Matrixm){ Matrixidentity={{1.0,0.0,0.0,0.0}, {0.0,1.0,0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; for(inti=0;i<4;i++) for(intj=0;j<4;j++) m[i][j]=identity[i][j];}voidpreMultiply(Matrixp,Matrixm){ inti,j; Matrixt; for(i=0;i<4;i++) for(j=0;j<4;j++) t[i][j]=p[i][0]*m[0][j]+p[i][1]*m[1][j]+p[i][2]*m[2][j]+p[i][3]*m[3][j]; for(i=0;i<4;i++) for(j=0;j<4;j++) m[i][j]=t[i][j];}voidrotate(floatangle,float*axis){ floatv[3]={axis[0],axis[1],0}, i[3]={1,0,0}, k[3]={0,0,1};loadIdentity(RM); normalize(v); floatr1=(v[1]<0)?acos(vv(v,i)):-acos(vv(v,i)); MatrixRz={{cos(r1),-sin(r1),0.0,0.0}, {sin(r1),cos(r1),0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(Rz,RM); floatr2=-acos(vv(axis,k)); MatrixRy={{cos(r2),0.0,sin(r2),0.0}, {0.0,1.0,0.0,0.0}, {-sin(r2),0.0,cos(r2),0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(Ry,RM); MatrixR={{cos(angle),-sin(angle),0.0,0.0}, {sin(angle),cos(angle),0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(R,RM); MatrixR_y={{cos(-r2),0.0,sin(-r2),0.0}, {0.0,1.0,0.0,0.0}, {-sin(-r2),0.0,cos(-r2),0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(R_y,RM); MatrixR_z={{cos(-r1),-sin(-r1),0.0,0.0}, {sin(-r1),cos(-r1),0.0,0.0}, {0.0,0.0,1.0,0.0}, {0.0,0.0,0.0,1.0}}; preMultiply(R_z,RM); preMultiply(RM,CRM);}voiddrawQMesh(){ inti,j; floatv1[3],v2[3],norm[3]; glBegin(GL_QUADS);for(i=0;i<n-1;i++) for(j=0;j<QMeshSize;j++){ v1[0]=QMesh[i+1][j+1][0]-QMesh[i][j][0];v1[1]=QMesh[i+1][j+1][1]-QMesh[i][j][1]; v1[2]=QMesh[i+1][j+1][2]-QMesh[i][j][2]; v2[0]=QMesh[i+1][j][0]-QMesh[i][j+1][0]; v2[1]=QMesh[i+1][j][1]-QMesh[i][j+1][1]; v2[2]=QMesh[i+1][j][2]-QMesh[i][j+1][2]; vxv(norm,v1,v2); glNormal3fv(norm); glVertex3fv(QMesh[i][j]); glVertex3fv(QMesh[i][j+1]); glVertex3fv(QMesh[i+1][j+1]); glVertex3fv(QMesh[i+1][j]); } glEnd();}voidmodelDisplay(){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT); glPushMatrix(); floatM[16]; for(intr=0;r<4;r++)for(intc=0;c<4;c++)M[4*c+r]=CRM[r][c]; glMultMatrixf(M); glScalef(zoom,zoom,zoom); drawQMesh(); glPopMatrix(); glPushMatrix();glLightfv(GL_LIGHT0,GL_AMBIENT,amb); glLightfv(GL_LIGHT0,GL_POSITION,lightPosition);glPopMatrix(); glutSwapBuffers();}voidmodelKeyboard(unsignedcharkey,intx,inty){ switch(key){ case'o':glMatrixMode(GL_PROJECTION); glLoadIdentity(); glOrtho(-4,4,-4,4,6,14); glMatrixMode(GL_MODELVIEW); break; case'p':glMatrixMode(GL_PROJECTION); glLoadIdentity(); gluPerspective(45.0,1.0,6.0,14.0); glMatrixMode(GL_MODELVIEW); break; case'x':lightPosition[0]=lightPosition[0]-0.5; break; case'X':lightPosition[0]=lightPosition[0]+0.5; break; case'y':lightPosition[1]=lightPosition[1]-0.5; break; case'Y':lightPosition[1]=lightPosition[1]+0.5; break; case'z':lightPosition[2]=lightPosition[2]-0.5; break; case'Z':lightPosition[2]=lightPosition[2]+0.5; break; case'W': case'w':glEnable(GL_FOG); { glFogi(GL_FOG_MODE,GL_LINEAR); GLfloatfogColor[]={1.9,1.1,2.2,0.5}; glFogfv(GL_FOG_COLOR,fogColor); glFogf(GL_FOG_START,3.0); glFogf(GL_FOG_END,15.0); glHint(GL_FOG_HINT,GL_DONT_CARE); } break; case'K': case'k':glDisable(GL_FOG); break; } glutPostRed

溫馨提示

  • 1. 本站所有資源如無特殊說明,都需要本地電腦安裝OFFICE2007和PDF閱讀器。圖紙軟件為CAD,CAXA,PROE,UG,SolidWorks等.壓縮文件請下載最新的WinRAR軟件解壓。
  • 2. 本站的文檔不包含任何第三方提供的附件圖紙等,如果需要附件,請聯系上傳者。文件的所有權益歸上傳用戶所有。
  • 3. 本站RAR壓縮包中若帶圖紙,網頁內容里面會有圖紙預覽,若沒有圖紙預覽就沒有圖紙。
  • 4. 未經權益所有人同意不得將文件中的內容挪作商業或盈利用途。
  • 5. 人人文庫網僅提供信息存儲空間,僅對用戶上傳內容的表現方式做保護處理,對用戶上傳分享的文檔內容本身不做任何修改或編輯,并不能對任何下載內容負責。
  • 6. 下載文件中如有侵權或不適當內容,請與我們聯系,我們立即糾正。
  • 7. 本站不保證下載資源的準確性、安全性和完整性, 同時也不承擔用戶因使用這些下載資源對自己和他人造成任何形式的傷害或損失。

評論

0/150

提交評論