第一篇:圖形學教案ch2.ppt.Convertor
計算機圖形學第二章 Turbo C的圖形功能
第二章
Turbo C 的圖形功能
圖形顯示器的兩種顯示模式:
文本模式和圖形模式
在文本方式下,屏幕上可顯示的最小單位是字符。文本方式設置不同,可顯示的字符的列數、行數也不相同(在一般缺省方式下,為25行、80列),顏色也有所區別。
在圖形方式下,屏幕上可以控制的單位叫做像素,它是組成圖形的基本元素,一般也成為“點”。分辨率越高,屏幕上包含的像素個數就越多,顯示的圖形越細,質量就越好。
屏幕上每個像素的位置可以用該像素在屏幕坐標系中的坐標進行描述。
屏幕坐標系是一個左手系,屏幕左上角為坐標系的原點(0,0),水平方向為X軸,自左向右;垂直方向為Y軸,自上而下。坐標范圍與顯示器的分辨率有關,例如,當分辨率為640×480時,左上角坐標為(0,0),右下角坐標為(639,479)。
一、圖形初始化及應用設置函數
因為在文本方式下不能顯示圖形,所有的圖形函數均不能操作,因此在使用圖形函數進行繪圖之前,必須將顯示適配器設置為圖形模式,即通常所說的“圖形模式初始化”。在繪圖結束之后,又要讓適配器的設置回到文本模式。Turbo C提供了14個函數,進行圖形系統的控制和管理工作。最常見的兩個函數是:
1、初始化圖形系統函數
void far initgraph(gdrive,gmode,gpath)int far *gdrive, *gmode, *gpath;gdrive:圖形驅動器代號,gmode:圖形模式代號,gpath: 圖形驅動程序路徑。如:常用方式:
int gdrive,gmode;gdrive=DETECT;initgraph(&gdrive,&gmode, “d:tc”);
2、釋放圖形系統所分配的內存、恢復屏幕原顯示模式函數
void far closegraph(void)調用形式:closegraph();
二、屏幕管理函數
1、擦除整個圖形屏幕,并將cp(當前位置)移到原點(0,0)
void far cleardevice(void)
2、建立視區
void setviewport(x1,y1,x2,y2)
3、清除視圖區
清除視圖區用函數clearviewport。它的作用是清除掉當前的視圖區,將當前點的位置重新設
1/7
計算機圖形學第二章 Turbo C的圖形功能
置為屏幕左上角(0,0)。其調用格式為:
clearviewport();
三、常用的作圖函數
1、畫點函數
putpixel(int x, int y, int color)
2、以當前顏色、線型、寬度畫直線函數
void line(x0, y0, x, y)
int x0, y0, x, y;從(x0,y0)畫到(x,y)。
3、以當前顏色、線型、寬度畫直線函數
void far lineto(int x, int y)從當前點(cp)畫到(x,y)。
4、得到當前位置坐標函數
(1)int far getx(void)
返回x坐標
(2)int far gety(void)
返回y坐標
5、以當前顏色、線型、線寬畫一矩形函數
void far rectangle(left, top, right, bottom)int left, top, right, bottom;
6、以當前填充模式、填充顏色畫一矩形函數
void far bar(left, top, right, bottom)int left, top, right, bottom;
7、以當前填充模式、填充顏色畫一多邊形函數
void far fillpoly(int num, int a[ ])num:頂點數;
a[ ]:存放各頂點坐標,共num*2個數;若是封閉的,則有num+1個點,有(num+1)*2個數。
8、以當前顏色、線型、線寬畫圓函數
void far circle(int x, int y, int radius)x, y:圓心坐標; radius:半徑。
9、以當前顏色、線型、線寬畫橢圓弧函數
void far ellipse(x, y, stangle, endangle, xradius, yradius)int x, y, stangle, endangle, xradius, yradius;x, y:橢圓中心坐標;
endangle, endangle:畫橢圓的起始角和終止角。若endangle=0, endangle=360,則畫一完整橢圓。
xradius,yradius:為x、y方向的軸長半徑。
10、以當前顏色、線型、線寬及填充模式、填充顏色畫扇形函數
void far piselice(x, y, stangle, endangle, radius)若stangle=0, endangle=360,則畫一完整圓。
2/7
計算機圖形學第二章 Turbo C的圖形功能
四、圖形屬性控制函數
1、得到背景顏色數值函數
int far getbkcolor(void)常調用形式: oldbkcolor=getbkcolor();
2、得到當前繪圖顏色數值函數
int far getcolor(void)常調用形式: oldcolor=getcolor();
3、設置背景顏色函數
void far setbkcolor(int color)調用形式如: setbkcolor(BLUE);
(蘭色背景)
4、設置當前繪圖顏色函數
void far setcolor(int color)調用形式如: setcolor(RED);
(紅色繪圖顏色)
5、獲得最大顏色數函數
int far getmaxcolor(void)調用形式如: maxclor= getmaxcolor();關于顏色值、符號常量與顏色的對應關系 符號常量
數值
顏色 BLACK
0
BLUE
GREEN
CYAN
青 RED
MAGENTA
品紅 BROWN
棕色 LIGHTGRAY
灰白 DARKGRAY
灰 LIGHTBLUE
LIGHTGREEN
LIGHTCYAN
淺青 LIGHTRED
LIGHTMAGENTA
淺品紅(淡紫色)YELLOW
WHITE
例
1、用16種不同的顏色顯示16條不同的線段 #include“graphics.h“
/*hhj01.c*/ main(){ int gdriver=DETECT,gmode;int i,y=0;initgraph(&gdriver,&gmode,”d: urboc2“);for(i=0;i<16;i++)
3/7
計算機圖形學第二章 Turbo C的圖形功能
{ setcolor(i);line(10,10+y,100,10+y);y+=5;} getch();closegraph();}
例、用直線生成(直紋)曲面
#include”graphics.h“
/*pattern.c*/ main(){ int y;long x;int gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,“d: urboc2”);cleardevice();setbkcolor(9);setcolor(4);for(y=0;y<=240;y+=5){
x=320/240*y;
line(0,y,x,240);
}
getch();
closegraph();
}
6、設置畫線寬度和線型的函數
void far setlinestyle(linestyle, upattern, thickness)
int linestyle, thickness;
unsigned upattern;linestyle(線型)取值,0:實線,1:點,2:長短,3:長虛線,4:自定義線型。thickness(寬度)取值: 1、3。
upattern:當linestyle為4時起作用。其他4種預定義情況可取0。例、顯示turbo c固有的畫線模式 /*line_style01.c*/ #include“graphics.h” main(){ int i,y=0,gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,“d: urboc2”);for(i=0;i<4;i++){
4/7
計算機圖形學第二章 Turbo C的圖形功能
setcolor(i+1);setlinestyle(i,0,1);line(10,100+y,100,100+y);y+=5;} getch();closegraph();}
例、用自定義線形畫線。/*line_style02.c*/ #include“graphics.h” main(){ int gdriver=DETECT,gmode;unsigned upattern=0XEBAE;initgraph(&gdriver,&gmode,“d: urboc2”);setcolor(1);setlinestyle(4,upattern,3);rectangle(100,100,300,300);getch();closegraph();}
7、設置著色(填充)模式和顏色函數
void far setfillstyle(int pattern, int color)pattern(著色模式)取值: 0:用背景顏色填充,1:用純色填充,2~12:用各種線型和色點填充。
color: 填充顏色。
8、填充封閉區域函數
void far floodfill(x, y, color)int x, y, color;x, y : 填充封閉區域中的一點;color:封閉區域的邊界顏色。/*bar3d.c* / #include“graphics.h“ main(){ int gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,”d: urboc2“);setcolor(3);setfillstyle(7,1);bar(200,200,300,300);getch();closegraph();}
5/7
計算機圖形學第二章 Turbo C的圖形功能
#include”graphics.h“ main(){ int i,gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,”d: urboc2“);setfillpattern(8,RED);setcolor(YELLOW);circle(200,200,100);floodfill(200,200,YELLOW);
/*pattern.c*/ getch();closegraph();}
9、設置用戶自定義的填充模式
void
setfillpattern(char *upattern,int color);其中,upattern是指針,指向8個字節,組成用戶定義的8×8點陣圖樣式。每個字節的8個二進制表示水平8點,8字節表示8行,然后以此模型向整個封閉區域填充。例、用setfillpattern()函數設置用戶自定義的填圖模式。char upattern[8]={0x00,0x24,0x7e,0x3c,0x3c,0x7e,0x24,0x00};#include”graphics.h“ main(){ int i,gdriver=DETECT,gmode;initgraph(&gdriver,&gmode,”d: urboc2");setfillpattern(upattern,RED);setcolor(YELLOW);circle(200,200,100);floodfill(200,200,YELLOW);
/*pattern.c*/ getch();closegraph();}
五、圖形方式下的文本
1、設置正文字形、顯示方向、字符大小函數
void far settextstyle(font, direction, charsize)int font, direction, charsize;font(字形)取值,0:8*8字形,1:3倍筆劃字形,2:小號筆劃字形,3:無襯線筆劃字形,4:黑體筆劃字形。
direction(顯示方向)取值,0:自左向右,1:由底向上。charsize(字符放大因子)取值,0:用戶自定義,1:8*8大小,2:16*16大小,??。最大為10倍。說明:該函數影響outtext()和outtextxy()兩個函數。
2、用當前對齊方式、字形、方向、大小在屏幕上(x,y)顯示字符串函數
6/7
計算機圖形學第二章 Turbo C的圖形功能
void far outtextxy(x, y, textstring)
int x, y;
char *textstring;(為字符串指針,不能是漢字)
3、用當前對齊方式、字形、方向、大小在屏幕上當前位置(cp)顯示字符串函數
void far outtext(textstring)char *textstring;(為字符串指針,不能是漢字)
六、字符屏幕控制函數
(包含在conio.h頭文件中)
1、清除屏幕并將光標移到左上角函數
void clrscr(void)
2、設置背景顏色函數
void textbackground(int color)
3、設置前景字符顏色函數
void textcolor(int color)
4、將光標移到指定位置函數
void gotoxy(int x, int y)
5、獲得光標位置函數
(1)int wherex(void),(2)int wherey(void)
6、向屏幕寫字符函數
printf(“%s%c”,變量表),puts(字符串)
7/7
第二篇:圖形學教案ch1.ppt.Convertor范文
計算機圖形學第一章 緒論
第一章
緒論
計算機圖形學(Computer Graphics)
使用計算機建立、存儲、處理某個具體的或抽象的對象的模型,并根據該模型產生該對象的圖形輸出的有關理論、方法和技術叫做計算機圖形學。是計算機科學中最為活躍、得到廣泛應用的分支之一。
計算機圖形學的主要研究內容
圖形硬件、圖形標準、圖形交互技術、光柵圖形生成算法、曲線曲面造型、實體造型、真實感圖形計算與顯示算法,以及科學計算可視化、計算機動畫、自然景物仿真、虛擬現實等。圖形與圖象
圖象純指計算機內以位圖(Bitmap)形式存在的灰度信息。圖形含有幾何屬性,更強調場景的幾何表示,是由場景的幾何模型和景物的物理屬性共同組成的。
圖形主要分為兩類
基于線條信息表示。如工程圖、等高線地圖、曲面的線框圖等。明暗圖(Shading)。即是通常所說的真實感圖形。
圖形軟件的分類
專用圖形(應用)軟件包和通用圖形程序設計軟件包。
專用軟件包的接口通常是一組菜單,用戶通過菜單與程序進行通信。例如,3DMAX、PHOTOSHOP、各種CAD系統等等。
通用軟件包提供了一個可用于C、C++、JAVA等高級語言的圖形函數庫。該圖形庫提供了用來描述基本圖元(如直線段、多邊形、球面、樣條曲線等)、設定顏色、場景的觀察以及對象的各種變換等的基本函數。例如,GKS(圖形核心系統)、PHIGS(程序員層次交互式圖形系統)、GL(圖形程序庫)、OpenGL(開放式圖形庫)、GIL(清華大學CAD中心開發)、VRML(Virtual-Reality Modeling Language,虛擬現實建模語言)等等。
計算機圖形學的發展歷史 1、50年代的準備和醞釀時期。2、60年代的確立和蓬勃發展時期。3、70年代的實用化時期。4、80年代的普及時期。5、90年代的標準化、集成化、智能化時期。
圖形硬件設備 顯示器:
目前應用最普及的是基于陰極射線管(CRT)的光柵掃描顯示器。陰極射線管(CRT)主要由電子槍、聚焦系統、加速電極、偏轉系統和熒光屏五部分組成。
隨機掃描顯示器
隨機掃描顯示器中的電子束的定位和偏轉具有隨機性。要顯示的圖形的定義是存放在刷
1/5
計算機圖形學第一章 緒論
新緩存的一組畫線命令。系統周期性地執行刷新緩存中的一組命令,根據當前的線條走向,由顯示控制器控制電子束的偏移,依次畫出其組成線條,從而在屏幕上產生圖形;當所有畫線命令處理完后,系統周期地返回到該刷新緩存的第一條畫線命令。因此,隨機掃描顯示器是畫線式顯示器,或矢量式顯示器。
存儲管式顯示器
缺點:不能用存儲管式顯示器產生動畫。存儲管式顯示器是畫線設備。
光柵掃描顯示器
光柵掃描方式將CRT屏幕分成由像素構成的光柵網格,其中像素具有灰度和顏色;所有像素的灰度和顏色信息(也稱為顯示內容)保存在一個專門的內存區域中,稱為幀緩沖存儲器(Frame Buffer),簡稱幀緩存。幀緩存的深度(位面數),即每個像素的位數決定了某一個顯示系統能顯示的顏色數。例如,1位深度幀緩存只能顯示兩種顏色,而8位深度幀緩存可以顯示28(=256)種顏色。在全色彩(full-color)系統里,深度為24位的圖形系統可以顯示足夠多的顏色數,能表示大多數真實感圖像,所以稱之為真彩色(true-color)系統。
在光柵掃描顯示器中,一幅圖像是由像素(pixel)陣列組成,而像素的陣列稱為光柵(raster)。一幅圖像的像素全部存放在一個稱為幀緩存器的內存里。幀緩存的深度(位面數),即每個像素的位數決定了某一個顯示系統能顯示的顏色數。例如,1位深度幀緩存只能顯示兩種顏色,而8位深度幀緩存可以顯示(2=256)種顏色。在全色彩(full-color)系統里,深度為24位的圖形系統可以顯示足夠多的顏色數,能表示大多數真實感圖像,所以稱之為真彩色(true-color)系統。
黑白單灰度光柵掃描顯示器 黑白多灰度光柵掃描顯示器 彩色單灰度光柵掃描顯示器 彩色多灰度光柵掃描顯示器
2/5
計算機圖形學第一章 緒論
一個具有24位面的幀緩沖存儲器,紅、綠、藍各8個位面,其值經數模轉換控制紅、綠、藍電子槍的強度,每支電子槍的強度有256(8位)個等級,則能顯示256*256*256=16兆種顏色,16兆種顏色也稱作(24位)真彩色。從以上的討論我們知道,像素的顏色數和幀緩存的大小是成正比的。為了節制幀緩存的增加,用盡量少的幀緩存來得到盡可能多的顏色數,提出了一種技術——查找表技術。
液晶顯示器(Liquid Crystal Display,簡稱LCD)
利用液晶的物理特性,通電時導通,晶體在電場作用下,排列變得有秩序,通過它的光的折射角度會發生變化,使光線容易通過;不通電時,晶體排列變得混亂,光被遮擋,不能通過。
等離子顯示器(Plasma Display Panel,簡稱PDP)
利用氣體放電激發熒光粉發光的顯示裝置。等離子管作為等離子顯示器的發光元件,大量的等離子管排列在一起構成屏幕。
平板顯示器具有超薄超輕、無輻射、低功耗等優良特性,近幾年來正在逐步普及。
刷新式隨機掃
隨機掃描顯示器 CRT顯示器(刷新式)光柵
存儲管式顯示器
圖形顯示器
液晶顯示器(LCD)
平板顯示器 等離子顯示器(PDP)
圖形繪制設備
1.繪圖儀
筆式繪圖儀(畫線設備)靜電繪圖儀(畫點設備)
2.打印機(畫點設備)點陣式打印機 噴墨打印機 激光打印機
常見的兩種顏色模型
RGB顏色模型
在這種顏色系統中,每一種基色的亮度可以從0到1,通過混合不同亮度的三種基色(紅、3/5
計算機圖形學第一章 緒論
綠、藍)可以表示多種顏色。由黑色開始,接著加入合適的基色得到希望的顏色。即RGB顏色系統是一個加色系統。
圖形顯示器使用的是RGB顏色系統。有紅、綠、藍三個電子槍,每個基色的亮度由調整電子槍轟擊熒光屏的強度獲得,通過混合不同亮度的三種基色可以在顯示器上得到相應的顏色。
CMY顏色模型
在CMY顏色模型中,由白色開始,接著減去合適的基色元素得到希望的顏色。CMY顏色系統是一個減色系統。例如,從白色中減去紅色就得到青色,減去綠色就得到品紅,減去蘭色就得到黃色等等。繪圖設備(如彩色噴墨打印機)使用的就是CMY顏色系統。
RGB顏色系統和CMY顏色系統的關系 例如,在CMY中,(1,1,1)表示黑顏色,而在RGB中,(0,0,0)表示黑顏色。(轉換公式見左下圖)例如,在CMY顏色模型中,(0,0,1)代表黃色,利用前面的轉換公式知道,在RGB顏色模型中,(1,1,0)表示黃色。因此紅色和綠色的混合產生黃色,因為投射光中的藍色成分被吸收了。
再如,在CMY顏色模型中,(1,1,0)表示青色和品紅墨水的混合,由轉換公式知,生成的顏色為藍色。這說明自然光投射到青色和品紅混合的墨水上時,光線中的紅色和綠色成分都被吸收了。
圖形輸入設備
第一階段:控制開關、穿孔紙等等
第二階段:鍵盤
第三階段:二維定位設備
如鼠標、光筆、圖形輸入板、觸摸屏、掃描儀 第四階段:三維輸入設備
?R??1??C???????G?1?M,????????B????1????Y????1??R???????1?G?????????1????B???C?
如空間球、數據手套、數據衣 M?圖形系統
?Y一個計算機圖形系統包括圖形硬件系統和圖形軟件系統。?圖形硬件系統應包括
(1)顯示處理器。(2)顯示存儲器。(3)幀緩存器。(4)圖形輸出設備。(5)圖形輸入設備。圖形軟件系統應包括專用的圖形軟件包(Photoshop、3DMAX、各種CAD等等)和通用的圖形(編程)軟件包(GKS、PHIGS、GL、OpenGL、GIL、VRML等等)。
計算機圖形學軟件系統
計算機圖形學軟件系統發展到目前已經非常豐富了,大致可以分為三類:
1、用某種高級語言寫成的子程序包*。
2、擴充某一種計算機語言,使其具有圖形的生成和處理功能。
3、專用的高級圖形語言。
*簡單的圖形系統有Photoshop、3DMAX、各種CAD等等。復雜的圖形系統有GKS、PHIGS、GL、OpenGL、GIL等等。
4/5
計算機圖形學第一章 緒論
圖形處理器
為了提高顯示系統的顯示能力和處理圖形的速度,以后發展的圖形處理器都增加了顯示處理器(顯示主芯片)GPU,具有很強的圖形處理功能。大大減輕了CPU的負擔,也提高了圖形顯示能力和速度。
GPU是圖形處理器的核心,其處理圖形的能力決定了圖形處理器的性能,一個好的3D卡支持硬件加速功能以及各種紋理渲染能力等。
顯示處理存儲器也稱為顯存。用于存儲將要顯示的圖形信息以及保存圖形運算的中間結果。它與GPU的關系就如同計算機的內存與CPU的關系一樣密不可分,顯存的大小和存取速度直接影響GPU性能的發揮。
詳細內容參見教材P24—P33
5/5
第三篇:圖形學實驗5
《3D游戲圖形學》
實驗報告書
(實驗五)
姓名:
學號: 班級:
浙江理工大學 二0一二 年 十二 月
數字圖像處理實驗指導書
實驗五 紋理映射實驗
一、實驗目的和要求
掌握紋理映射的基本原理,利用VC++ OpenGL實現紋理映射技術。
二、實驗原理
紋理映射是真實感圖形制作的一個重要部分,運用紋理映射可以方面地制作真實感圖形,而不必花更多的時間去考慮物體的表面紋理。如一張木制桌子其表面的木紋是不規范的,看上去又是那么自然,如果在圖形制作中不用紋理映射,那么只是這張桌面紋理的設計,就要花費很大精力,而且設計結果也未必能像現實中那么自然。如果運用紋理映射就非常方便,可以用掃描儀將這樣的一張桌子掃成一個位圖。然后的具體的操作中,只需把桌面形狀用多邊形畫出來,把桌面紋理貼上去就可以了。
另外,紋理映射能夠在多邊形進行變換時仍保證紋理的圖案與多邊形保持一致性。例如,以透視投影方式觀察墻面時,遠端的磚會變小,而近處的磚就會大一些。
此外,紋理映射也可以用于其他方面。例如,使用一大片植被的圖像映射到一些連續的多邊形上,以模擬地貌,或者以大理石、木紋等自然物質的圖像作為紋理映射到相應的多邊形上,作為物體的真實表面。
在OpenGL中提供了一系列完整的紋理操作函數,用戶可以用它們構造理想的物體表面,可以對光照物體進行處理,使其映射出所處環境的景象,可以用不同方式應用到曲面上,而且可以隨幾何物體的幾何屬性變換而變化,從而使制作的三維場景和三維物體更真實更自然。
在OpenGL中要實現紋理映射,需要經歷創建紋理、指定紋理應用方式、啟用紋理映射、使用紋理坐標和幾何坐標繪制場景幾個過程。
用于指定一維、二維和三維紋理的函數分別為: Void glTexImage1D(GLenum target, Glint level, Glint components, GLsizei width, Glint border, GLenum format, GLenum type, const GLvoid *texels);Void glTexImage2D(GLenum target, Glint level, Glint components, GLsizei width, GLsizei height, GLint border, GLenum format, GLenum type, const GLvoid *texels);Void glTexImage3D(GLenum target, Glint level, Glint components, GLsizei width, GLsizei height, GLsizei depth, Glint border, GLenum format, GLenum type, const GLvoid *texels);其中,參數target取值一般為GL_TEXTURE_1D, GL_TEXTURE_2D和GL_TEXTURE_3D,分別與一維、二維和三維的紋理相對應。參數Level表示紋理多分辨率層數,通常取值為0,表示只有一種分辨率。參數components的可能取值為1~4的整數以及多種符號常量(如GL_RGBA),表示紋理元素中存儲的哪些分量(RGBA顏色、深度等)在紋理映射中被使用,1表示使用R顏色分量,2表示使用R和A顏色分量,3表示使用RGB顏色分量,4表示使用RGBA顏色分量。參數width,height,depth分別指定紋理的寬度、高度、深度。參數format和type表示給出的圖像數據的數據格式和數據類型,這兩個參數的取值都是符號常量(比如format指定為GL_RGBA,type指定為GL_UNSIGNED_BYTE,參數texels指向內存中指定的紋理圖像數據。
在定義了紋理之后,需要啟用紋理的函數: 數字圖像處理實驗指導書
glEnable(GL_TEXTURE_1D);glEnable(GL_TEXTURE_2D);glEnable(GL_TEXTURE_3D);在啟用紋理之后,需要建立物體表面上點與紋理空間的對應關系,即在繪制基本圖元時,在glVertex函數調用之前調用glTexCoord函數,明確指定當前頂點所對應的紋理坐標,例如:
glBegin(GL_TRIANGLES);glTexCoord2f(0.0, 0.0);glVertex2f(0.0, 0.0);glTexCoord2f(1.0, 1.0);glVertex2f(15.0, 15.0);glTexCoord2f(1.0, 0.0);glVertex2f(30.0, 0.0);glEnd();其圖元內部點的紋理坐標利用頂點處的紋理坐標采用線性插值的方法計算出來。
在OpenGL中,紋理坐標的范圍被指定在[0,1]之間,而在使用映射函數進行紋理坐標計算時,有可能得到不在[0,1]之間的坐標。此時OpenGL有兩種處理方式,一種是截斷,另一種是重復,它們被稱為環繞模式。在截斷模式(GL_CLAMP)中,將大于1.0的紋理坐標設置為1.0,將小于0.0的紋理坐標設置為0.0。在重復模式(GL_REPEAT)中,如果紋理坐標不在[0,1]之間,則將紋理坐標值的整數部分舍棄,只使用小數部分,這樣使紋理圖像在物體表面重復出現。例如,使用下面的函數:
glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP);glTexParameterf(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_REPEAT);分別指定二維紋理中s坐標采用截斷或重復處理方式。
另外,在變換和紋理映射后,屏幕上的一個像素可能對應紋理元素的一小部分(放大),也可能對應大量的處理元素(縮小)。在OpenGL中,允許指定多種方式來決定如何完成像素與紋理元素對應的計算方法(濾波)。比如,下面的函數可以指定放大和縮小的濾波方法:
glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_NEAREST);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_NEAREST);其中,glTexParameteri函數的第一個參數指定使用的是一維、二維或三維紋理;第二個參數為GL_TEXTURE_MAG_FILTER或GL_TEXTURE_MIN_FILTER,指出要指定縮小還是放大濾波算法;最后一個參數指定濾波的方法。
補充:透視投影函數
void gluPerspective(GLdouble fovy, GLdouble aspect, GLdouble zNear, GLdouble zFar);它也創建一個對稱透視視景體,但它的參數定義于前面的不同。其操作是創建一個對稱的透視投影矩陣,并且用這個矩陣乘以當前矩陣。參數fovy定義視野在X-Z平面的角度,范圍是[0.0,180.0];參數aspect是投影平面寬度與高度的比率;參數zNear和Far分別是遠近裁剪面沿Z負軸到視點的距離,它們總為正值。
三、實驗內容
在OpenGL中紋理映射所使用的紋理數據,既可以是程序生成的一組數據,也可以從外部文件中直接讀取,參考示范代碼完成以下兩項內容: 1.利用直接創建紋理的方法生成二維紋理并映射到四邊形上。參考代碼:
void makeImage(void){ 數字圖像處理實驗指導書
int i, j, r,g,b;for(i = 0;i < ImageWidth;i++){
for(j = 0;j < ImageHeight;j++)
{
r=(i*j)%255;
g=(4*i)%255;
b=(4*j)%255;
Image[i][j][0] =(GLubyte)r;
Image[i][j][1] =(GLubyte)g;
Image[i][j][2] =(GLubyte)b;
} }} void myinit(void){ glClearColor(0.0, 0.0, 0.0, 0.0);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);// 生成紋理數據 makeImage();// 設置像素存儲模式
glPixelStorei(GL_UNPACK_ALIGNMENT, 1);// 定義二維紋理映射 glTexImage2D(……);// 定義紋理映射參數 glTexParameterf(……);glTexParameterf(……);glTexParameterf(……);glTexParameterf(……);// 啟用二維紋理
glEnable(GL_TEXTURE_2D);glShadeModel(GL_FLAT);} void display(void){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT);//繪制四邊形,并完成紋理映射
……
glFlush();} void myReshape(GLsizei w, GLsizei h){ ……} void main(int argc, char* argv[]){ ……} 2.從外部文件中直接讀取紋理實現正方體每個面的紋理映射,并使正方體轉動。
數字圖像處理實驗指導書
整個過程需要三個步驟:創建紋理、啟用紋理映射和使用紋理坐標和幾何坐標繪制,下面我們對三個過程進行闡述,并給出參考代碼。1)創建紋理對象并綁定紋理
紋理創建即在內存中創建保存紋理數據的數組,一般是先讀入一個圖像文件,將圖像文件的RGBA信息存入我們創建的紋理空間中,當然圖像的位圖不同,創建的紋理空間結構也會有所不同。為了更加簡單易懂地實現這個過程,我們使用未壓縮的紋理。代碼:
GLuinttexture[1];//創建一個紋理空間
AUX_RGBImageRec *LoadBMP(CHAR *Filename)//載入位圖圖像 { FILE *File=NULL;//文件句柄
if(!Filename)//確保文件名已提供
{
return NULL;} File=fopen(Filename, “r”);//嘗試打開文件
if(File){
fclose(File);//關閉文件
return auxDIBImageLoadA(Filename);//載入位圖并返回指針
} return NULL;} //如果載入失敗,返回NULL int LoadGLTextures()//載入位圖并轉換成紋理 { int Status=FALSE;//狀態指示器
AUX_RGBImageRec *TextureImage[1];//創建紋理的存儲空間
memset(TextureImage, 0, sizeof(void *)*1);//初始化 //載入位圖,檢查有無錯誤,如果位圖沒找到則退出
if(TextureImage[0]=LoadBMP(“data.bmp”)){
Status=TRUE;
glGenTextures(1,&texture[0]);//創建紋理 //使用來自位圖數據生成的典型紋理
glBindTexture(GL_TEXTURE_2D, texture[0]);//生成2D紋理
glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);} if(TextureImage[0])//紋理是否存在{
if(TextureImage[0]->data)//紋理圖像是否存在 { 數字圖像處理實驗指導書
free(TextureImage[0]->data);//釋放紋理圖像占用的內存
}
free(TextureImage[0]);//釋放圖像結構
} return Status;//返回Status }
2)啟用紋理映射操作,初始化相關參數
在OpenGL中使用紋理映射之前,必須打開紋理映射。int InitGL(GLvoid){ if(!LoadGLTextures())//調用紋理載入子例程
{
return FALSE;} glEnable(GL_TEXTURE_2D);//啟用紋理映射
glShadeModel(GL_SMOOTH);//啟用陰影平滑
glClearColor(0.0f, 0.0f, 0.0f, 0.5f);//黑色背景
glClearDepth(1.0f);//設置深度緩存
glEnable(GL_DEPTH_TEST);//啟用深度測試
return TRUE;}
3)使用紋理坐標和幾何坐標繪制 void DrawGLScene(void){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);glLoadIdentity();glTranslatef(0.0f,0.0f,-5.0f);glRotatef(xrot,1.0f,0.0f,0.0f);glRotatef(yrot,0.0f,1.0f,0.0f);glRotatef(zrot,0.0f,0.0f,1.0f);// 選擇紋理
glBindTexture(GL_TEXTURE_2D,texture[0]);//繪制一個正方體,給每個面貼上紋理,并使之轉動
glBegin(GL_QUADS);……
glEnd();xrot+=0.3f;yrot+=0.2f;zrot+=0.4f;}
四、實驗代碼 數字圖像處理實驗指導書
1、利用直接創建紋理的方法生成二維紋理并映射到四邊形上。#include
#define imageWidth 64 #define imageHeight 64 GLubyte image[imageWidth][imageHeight][3];
/*繪制一個簡單的二維紋理圖*/ void makeImage(void){ int i,j,r,g,b;
/*根據點的位置設置不同的顏色*/ for(i = 0;i < imageWidth;i++){
for(j = 0;j r =(i*j)%255; g =(i*i)%255; b =(j*j)%255; image[i][j][0] =(GLubyte)r; image[i][j][1] =(GLubyte)g; image[i][j][2] =(GLubyte)b; } } } void myInit(void){ glClearColor(0.0,0.0,0.0,0.0);glEnable(GL_DEPTH_TEST);glDepthFunc(GL_LESS);// 生成紋理數據 makeImage();// 設置像素存儲模式 glPixelStorei(GL_UNPACK_ALIGNMENT,1);/*指定二維紋理映射*/ glTexImage2D(GL_TEXTURE_2D,0,3,imageWidth,imageHeight,0,GL_RGB,GL_UNSIGNED_BYTE,&image[0][0][0]);//紋理過濾函數 /*GL_TEXTURE_2D: 操作D紋理.GL_TEXTURE_WRAP_S: S方向上的貼圖模式.GL_CLAMP: 將紋理坐標限制在.0,1.0的范圍之內.如果超出了會如何呢.不會錯誤,只是會邊緣拉伸填充.GL_TEXTURE_MAG_FILTER: 放大過濾 GL_LINEAR: 線性過濾, 使用距離當前渲染像素中心最近的個紋素加權平均值.數字圖像處理實驗指導書 GL_TEXTURE_MIN_FILTER: 縮小過濾 GL_LINEAR_MIPMAP_NEAREST: 使用GL_NEAREST對最接近當前多邊形的解析度的兩個層級貼圖進行采樣,然后用這兩個值進行線性插值.*/ glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_S,GL_CLAMP);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_WRAP_T,GL_CLAMP);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MAG_FILTER,GL_NEAREST);glTexParameterf(GL_TEXTURE_2D,GL_TEXTURE_MIN_FILTER,GL_NEAREST);/*設置紋理環境參數*/ //glTexEnvf(GL_TEXTURE_ENV,GL_TEXTURE_ENV_MODE,GL_DECAL);// 啟用二維紋理 glEnable(GL_TEXTURE_2D);glShadeModel(GL_FLAT);} void myDisplay(void){ glClear(GL_COLOR_BUFFER_BIT|GL_DEPTH_BUFFER_BIT);/*將紋理映射到四邊形上*/ glBegin(GL_QUADS);/*紋理的坐標和四邊形頂點的對應*/ glTexCoord2f(0.0,0.0);glVertex3f(-0.7,-0.25,0.0);glTexCoord2f(0.0,1.0);glVertex3f(-0.2,-0.25,0.0);glTexCoord2f(1.0,1.0);glVertex3f(-0.2,0.25,0.0);glTexCoord2f(1.0,0.0);glVertex3f(-0.7,0.25,0.0);glTexCoord2f(0.0,0.0);glVertex3f(0.2,-0.25,1.875);glTexCoord2f(0.0,1.0);glVertex3f(0.6,-0.25,0.0);glTexCoord2f(1.0,1.0);glVertex3f(0.6,0.25,0.125);glTexCoord2f(1.0,0.0);glVertex3f(0.2,0.25,2.0);glEnd();glFlush();} void myReshape(int w,int h){ glViewport(0,0,(GLsizei)w,(GLsizei)h);glMatrixMode(GL_PROJECTION);glLoadIdentity();gluPerspective(80.0,1.0-(GLfloat)w/(GLfloat)h,1.0,30.0);glMatrixMode(GL_MODELVIEW);glLoadIdentity();} int main(int argc,char **argv){ /*初始化*/ glutInit(&argc,argv);glutInitDisplayMode(GLUT_SINGLE|GLUT_RGB);glutInitWindowSize(400,400);數字圖像處理實驗指導書 glutInitWindowPosition(200,200);glutCreateWindow(“ Texture ”);//創建窗口 myInit();//繪制與顯示 glutReshapeFunc(myReshape);glutDisplayFunc(myDisplay);glutMainLoop();return 0;} 2、從外部文件中直接讀取紋理實現正方體每個面的紋理映射,并使正方體轉動。#include #include #include #include #include #pragma comment(lib, “openGL32.lib”)#pragma comment(lib, “glu32.lib”)#pragma comment(lib, “glaux.lib”)#pragma comment(lib,“openGL32.lib”)GLuint texture[1];//創建紋理空間 GLfloat xRot,yRot,zRot;//控制正方體的旋轉 //載入位圖圖像 AUX_RGBImageRec *LoadBMP(CHAR *Filename){ //載入位圖圖像 FILE *File=NULL; //文件句柄 if(!Filename){ //確保文件名已提供 return NULL;} File=fopen(Filename, “r”); //嘗試打開文件 if(File){ fclose(File); //關閉文件 return auxDIBImageLoadA(Filename); //載入位圖并返回指針 } return NULL; //如果載入失敗,返回NULL } int LoadGLTextures(){ //載入位圖并轉換成紋理 int Status=FALSE; //狀態指示器 AUX_RGBImageRec *TextureImage[1]; //創建紋理的存儲空間 memset(TextureImage, 0, sizeof(void *)*1);//初始化 //載入位圖,檢查有無錯誤,如果位圖沒找到則退出 if(TextureImage[0]=LoadBMP(“data.bmp”)){ Status=TRUE; glGenTextures(1,&texture[0]); //創建紋理 //使用來自位圖數據生成的典型紋理 glBindTexture(GL_TEXTURE_2D, texture[0]); //生成D紋理 數字圖像處理實驗指導書 glTexImage2D(GL_TEXTURE_2D,0,3,TextureImage[0]->sizeX,TextureImage[0]->sizeY, 0, GL_RGB, GL_UNSIGNED_BYTE, TextureImage[0]->data);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR);glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR);} if(TextureImage[0]){ //紋理是否存在if(TextureImage[0]->data){ //紋理圖像是否存在free(TextureImage[0]->data); //釋放紋理圖像占用的內存 } free(TextureImage[0]); //釋放圖像結構 } return Status; //返回Status } int InitGL(GLvoid){ if(!LoadGLTextures()){ //調用紋理載入子例程 return FALSE;} glEnable(GL_TEXTURE_2D); //啟用紋理映射 glShadeModel(GL_SMOOTH); //啟用陰影平滑 glClearColor(0.0f, 0.0f, 0.0f, 0.5f); //黑色背景 glClearDepth(1.0f); //設置深度緩存 glEnable(GL_DEPTH_TEST); //啟用深度測試 return TRUE;} void display(){ glClear(GL_COLOR_BUFFER_BIT | GL_DEPTH_BUFFER_BIT); glLoadIdentity(); glTranslatef(0.0f,0.0f,-5.0f); glRotatef(xRot,1.0f,0.0f,0.0f); glRotatef(yRot,0.0f,1.0f,0.0f); glRotatef(zRot,0.0f,0.0f,1.0f); //繪制正方體,貼上紋理并使之轉動 glBindTexture(GL_TEXTURE_2D,texture[0]);//選擇紋理 glBegin(GL_QUADS); //前 glTexCoord2f(0.0f, 0.0f);glVertex3f(-1.0f,-1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(1.0f,-1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(-1.0f, 1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture[0]); glBegin(GL_QUADS); //后 glTexCoord2f(1.0f, 0.0f);glVertex3f(-1.0f,-1.0f,-1.0f);數字圖像處理實驗指導書 glTexCoord2f(1.0f, 1.0f);glVertex3f(-1.0f, 1.0f,-1.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(1.0f, 1.0f,-1.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(1.0f,-1.0f,-1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture[0]); glBegin(GL_QUADS); // 上 glTexCoord2f(0.0f, 1.0f);glVertex3f(-1.0f, 1.0f,-1.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(1.0f, 1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(1.0f, 1.0f,-1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture[0]); glBegin(GL_QUADS); //下 glTexCoord2f(1.0f, 1.0f);glVertex3f(-1.0f,-1.0f,-1.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(1.0f,-1.0f,-1.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(1.0f,-1.0f, 1.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(-1.0f,-1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture[0]); glBegin(GL_QUADS); //右 glTexCoord2f(1.0f, 0.0f);glVertex3f(1.0f,-1.0f,-1.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(1.0f, 1.0f,-1.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 0.0f);glVertex3f(1.0f,-1.0f, 1.0f); glEnd(); glBindTexture(GL_TEXTURE_2D,texture[0]); glBegin(GL_QUADS); //左 glTexCoord2f(0.0f, 0.0f);glVertex3f(-1.0f,-1.0f,-1.0f); glTexCoord2f(1.0f, 0.0f);glVertex3f(-1.0f,-1.0f, 1.0f); glTexCoord2f(1.0f, 1.0f);glVertex3f(-1.0f, 1.0f, 1.0f); glTexCoord2f(0.0f, 1.0f);glVertex3f(-1.0f, 1.0f,-1.0f); glEnd(); glutPostRedisplay(); glutSwapBuffers(); } void reshape(int w,int h){ if(0 == h) h = 1; glViewport(0,0,(GLsizei)w,(GLsizei)h); glMatrixMode(GL_PROJECTION);數字圖像處理實驗指導書 glLoadIdentity(); gluPerspective(60.0f,(GLfloat)w /(GLfloat)h,1,100); glMatrixMode(GL_MODELVIEW); glLoadIdentity(); } void spinDisplay(void){ xRot += 0.2f; yRot += 0.2f; glutPostRedisplay();} void mouse(int button, int state, int x, int y)//鼠標監聽 { switch(button){ case GLUT_LEFT_BUTTON: if(state == GLUT_DOWN) glutIdleFunc(spinDisplay);//設備空閑時調用的函數 break; case GLUT_MIDDLE_BUTTON: case GLUT_RIGHT_BUTTON: if(state == GLUT_DOWN) glutIdleFunc(NULL); break; default: break; } } int main(int argc,char** argv){ glutInit(&argc,argv); glutInitDisplayMode(GLUT_DOUBLE | GLUT_RGB); glutInitWindowSize(400,400); glutInitWindowPosition(100,100); glutCreateWindow(“Texture Map”); InitGL(); glutDisplayFunc(display); glutReshapeFunc(reshape); glutMouseFunc(mouse);//鼠標監聽 glutMainLoop(); return 0; } 五、實驗結果 1、利用直接創建紋理的方法生成二維紋理并映射到四邊形上。數字圖像處理實驗指導書 2、從外部文件中直接讀取紋理實現正方體每個面的紋理映射,并使正方體轉動。(按左鍵轉動,按右鍵停止) 六、實驗心得 《計算機圖形學》學習報告 ? 東西方建筑中的理性 盡管東方“木構”的暫時性文化和西方“石砌”的永久性文化氛圍造成了建筑形式風格的差異,但是它們都兼有理性和感性美。從柱式的英文“order”一詞,到中國古建筑等級制的基數開間,無不透露著匠人的理性思考;從古埃及繪畫中為了將人的特征最大限度表現而作的頭部側面身體正面的繪畫,到文藝復興達芬奇創造的透視畫法,一步步將人們引向更為理性的世界。 西方古典主義者強調構圖中的主從關系,突出軸線、講求配稱;倡導理性,主張建筑的真實,反對表現感情和情緒。隨之而來的比例、節奏、韻律、秩序美,是建筑區別于雕塑和繪畫兩大藝術的特點。 維特魯威提出的建筑三原則:堅固、適用、美觀,時時刻刻提醒著我們建筑是要被建造起來的,它是我們的“避難所”,需要理性的結構、縝密的分析和思考。時代在進步,建筑理論從勒杜克的結構理性主義發展到現在的解構主義,再也不是建筑形式適應結構的時代了,而是兩者互為促進。 我們對建筑的理解不再是像路易斯康那樣再去問磚想做什么,等待它做拱卷的回答。我們向大自然學習,卡拉特拉瓦創造了許多帶有理性美的仿生建筑。當我們想進一步拓寬我們的思維時,我們還能向誰求助?計算機圖形學為我們打開了理性思考的一扇窗。 ? 計算機圖形學對理性建筑的貢獻 半個多世紀以來,計算機技術得到了飛速的發展。它的進步不僅僅使世界變得更平,信息交流更便捷,在此平臺上開發的各種繪圖軟件更是將建筑師從傳統的手工渲染畫圖中解放出來,也解放了結構師的工作量。用了30年的時間,計算機的速度從K(103)到T(1012),而從T到Z(1021),我們只用了10年時間。發展的速度是越來越快,我們設計方法和速度都得到了革新。這是這樣一個數字化信息化的時代,才有弗蘭克蓋里建筑的夸張和扎哈哈迪德設計的新奇。 原來我們隨手繪出的自由曲線,現在計算機都能幫我們算出是否有建造的可能,以及建筑性能也能在建造前得到分析。在創意上,計算機也能將我們模糊的概念無限發展,給它一個規則,它可能還你一個超乎想象的造型,在理性規則中生成感性而自由的建筑。 知其然,還應知其所以然,看著電視機的變薄,圖像更加逼真,這變化的一切都建立在計算機圖形學的架構下,了解了基礎原理,才能更高效地做高質量的建筑設計。 ? 計算機圖形學的理論知識 1.相關概念 計算機圖形學是主要研究通過計算機處理用集合數據和數學模型所描述的圖形的原理、算法和系統。包括圖形的輸入、存儲、運算、轉換、傳送和輸出。數字化技術是泛指在某特定領域利用包括硬件、軟件在內的計算機與電子技術以及數學或數字模型等描述的問題進行求解、模擬或分析活動的一切應用技術。 建筑數字化技術研究應用包括建筑的數字化設計和反映建筑的數字化特征在內的數字技術。而建筑數字化技術的核心幾何學科就是計算機圖形學。2.反映建筑數字化特征的典型圖形技術 建筑的動態特征——圖形顯示:如奧地利格拉茨美術館的925盞燈形成的外墻面顯示屏 建筑的互動特征——圖形顯示:如杜瑟赫姆市的隨情感變化而色彩變化的建筑物 建筑的數字特征——幾何運算:如柏林Max Reinhardt大樓模型及“莫比烏斯環”變換 建筑的虛實特征——交互式圖形:如法國國立圖書館(實體與網絡圖書館) 設計手段和設計媒體的數字化特征——交互式圖形:如紐約韓國基督教長老會教堂 而建筑性能如聲環境、熱環境、光環境、風環境模擬的可視化分析中都用到了圖形學。3.虛擬現實技術(VR) 虛擬現實技術是計算機生成的給人多種感官刺激的虛擬世界(環境),是一種高級的人機交互系統。 虛擬現實技術的三個基本特征:沉浸感、交互性、想象力 它具有多學科的綜合性,正如建筑學是一門綜合的藝術,虛擬現實技術包括圖像處理、圖形學、計算幾何、多傳感器、網絡、多媒體和仿真技術等。 正如課堂上老師放映的《碟中諜4》,逼真的爆炸場景,以及從皮克斯動畫開始的動物毛發到最近火熱的《少年派》逼真的老虎與人共存畫面,虛擬現實技術的進步影響到了我們生活的方方面面,觸到了我們原來想都不敢想的世界。 而VR技術在建筑行業中,有以下作用:(1)指導設計:讓建筑師通過瀏覽觀察和了解空間關系,特別是對空間大小、方向、形狀和建筑元素行為的理解。(2)建筑表現與環境仿真(3)仿真施工:檢查和修改施工細節、合理性和有效性 4.虛擬現實的基礎與關鍵技術:建模與描繪 基于幾何和圖形學的建模和描繪技術 直接幾何建模 3D掃描建模 投影視圖建模 基于圖像的場景描繪技術(IBR) 圖像投影變形技術 光場重建技術 混合式IBR技術 IBR技術圖形的繪制獨立于場景的復雜性,僅僅與所要生成畫面的分辨率有關。 實驗三 MFC畫直線 最近自己在學習如何在VC 6.0 開發環境下的使用MFC AppWizard(exe)來繪畫一條直線,雖然比較簡單,通過這樣的練習可以幫助你熟悉MFC的開發環境以及其中的消息傳遞機制,希望對于像我一樣初入MFC圖形繪制學習的人有幫 助 第一步:構建MFC窗體 打開Visual C++ 6.0編譯器 新建→工程→MFC AppWizard(exe),工程名以DrawLine為例,然后確定。為了方便,在MFC應用程序向導—步驟1當中選擇“單文檔”,其余所有的步驟都為默認值,直接“完成”。這樣一個簡單的MFC窗體就構建好了,自己不妨Compile—Build—BuildExecute一下。 第二步:編輯菜單項 選擇ResourceView視窗展開Menu文件夾,左鍵雙擊IDR_DRAWLITYPE,右邊就會出現菜單圖形編輯界面,為了簡化,我們只在添加幫助→DrawLine功能選擇項。雙擊空白會彈出“菜單項目 屬性”對話框。ID:ID_DRAW_LINE;標明: DrawLine(&D),其它的為缺省。 第三步:建立消息命令 如果此時運行該程序,你會發現幫助—DrawLine的功能選項是灰色的,原因就在于我們還沒有添加該功能的消息命令相應函數。通過“查看—Message Maps—Project:DrawLine—Class name:CDrawLineView—Object IDs:ID_DRAW_LINE—選定COMMAND—Add Function?”,其它為默認,最后確定完成。現在如果再重新運行該程序的話,會發現原來的灰色已經消除了。 第四步:添加鼠標消息響應 打開ClassView視窗,右鍵選定CDrawLineView,選擇Add Windows Messsage Handler會彈出對話框,完成CDrawLineView類的WM_LBUTTONDOWN、WM_MOUSEMOVE、WM_LBUTTONUP三個Windows消息事件的新建。 第五步:添加響應代碼 首先,在ClassView視窗中雙擊CDrawLineView會定位到“DrawLineView.h : interface of the CDrawLineView class”的文件,添加CDrawLineView類的成員:protected: int m_Drag;POINT m_pPrev;POINT m_pOrigin;三個成員變量。視窗中展開CDrawLineView類,雙擊定位OnLBUTTONDOWN()函數。在該函數消息響應 處添加如下代碼: //建立好繪圖的設備環境 CClientDC dc(this);OnPrepareDC(&dc); dc.DPtoLP(&point); //獲取起始點坐標 m_pPrev=point;m_pOrigin=point; m_Drag=1; 然后,定位于OnMouseMove(),添加如下代碼(其中關鍵用到了橡皮筋技術): //建立好繪圖的設備環境 CClientDC dc(this); OnPrepareDC(&dc);dc.DPtoLP(&point); dc.SetROP2(R2_NOT);//橡皮筋繪圖技術 //判斷是否BUTTONDOWN if(m_Drag) { dc.MoveTo(m_pOrigin);dc.LineTo(m_pPrev);dc.MoveTo(m_pOrigin);dc.LineTo(point); } m_pPrev=point; 最后,在OnLBUTTONDOWN()添加代碼: m_Drag=0; 程序運行效果圖 實驗4 實現圓的生成算法 一、實驗目的 1.熟悉CDC圖形程序庫; 2.掌握中點畫圓生成算法; 3.掌握Bresenham畫圓算法。 二、實驗內容 利用VisualC++6.0設計一個簡易畫圓繪圖板,驗證圓生成算法。 三、實驗指導 1.生成繪圖應用程序的框架,如下圖所示。具體實現見第二次實驗,過程不再詳細說明。 2.在應用程序中增加菜單 完成相關菜單的設計,具體的效果如下圖所示,并設置好相關菜單消息的映射,具體的實現在前面的實驗中介紹過,再此不在詳細說明。 3.在繪圖函數中添加代碼 通過以上步驟,得到了與菜單對應的消息映射,就可以在函數中添加代碼繪制圖形了。(1)利用中點畫圓算法實現圓的生成(算法原理見教材)。void CDraw_CirView::OnMid(){ // TODO: Add your command handler code here CDC*pDC=GetDC();//得到繪圖類指針 RedrawWindow();//重繪窗口 int x,y,x0=200,y0=200,r=100;//圓的圓心為(x0,y0),半徑為r float d;x=0;y=r;d=1.25-r; pDC->SetPixel(x+x0,y+y0,RGB(255,0,0));pDC->SetPixel(y+x0,x+y0,RGB(255,0,0));pDC->SetPixel(y+x0,-x+y0,RGB(255,0,0));pDC->SetPixel(x+x0,-y+y0,RGB(255,0,0));pDC->SetPixel(-x+x0,-y+y0,RGB(255,0,0));pDC->SetPixel(-y+x0,-x+y0,RGB(255,0,0));pDC->SetPixel(-y+x0,x+y0,RGB(255,0,0));pDC->SetPixel(-x+x0,y+y0,RGB(255,0,0));while(x<=y){ if(d<0) { d=d+2*x+3; x++; } else { d=d+2*(x-y)+5; x++; y--;} pDC->SetPixel(x+x0,y+y0,RGB(255,0,0)); pDC->SetPixel(y+x0,x+y0,RGB(255,0,0)); pDC->SetPixel(y+x0,-x+y0,RGB(255,0,0)); pDC->SetPixel(x+x0,-y+y0,RGB(255,0,0)); pDC->SetPixel(-x+x0,-y+y0,RGB(255,0,0)); pDC->SetPixel(-y+x0,-x+y0,RGB(255,0,0)); pDC->SetPixel(-y+x0,x+y0,RGB(255,0,0)); pDC->SetPixel(-x+x0,y+y0,RGB(255,0,0));} } 由以上代碼繪出的圖形如下: (2)利用Bresenham算法生成圓(算法原理見教材)。void CDraw_CirView::OnBre(){ // TODO: Add your command handler code here CDC*pDC=GetDC();//得到繪圖類指針 //RedrawWindow();//重繪窗口 int x,y,x0=200,y0=200,r=50;//圓的圓心為(x0,y0),半徑為r int delta,delta1,delta2,direction;x=0;y=r;delta=2*(1-r);while(y>=0){ pDC->SetPixel(x+x0,y+y0,RGB(0,0,255)); pDC->SetPixel(x+x0,-y+y0,RGB(0,0,255)); pDC->SetPixel(-x+x0,y+y0,RGB(0,0,255)); pDC->SetPixel(-x+x0,-y+y0,RGB(0,0,255)); if(delta<0) { delta1=2*(delta+y)-1; if(delta<=0)direction=1; else direction=2; } else if(delta>0) { delta2=2*(delta-x)-1; if(delta2<=0)direction=2; else direction=3; } else direction=2; switch(direction) { case 1:x++; delta+=2*x+1; break; case 2:x++;y--; delta+=2*(x-y+1); break; case 3:y--; delta+=(-2*y+1); break; } } } 由以上代碼繪出的圖形如下: (3)以上是本次實驗的基本部分,利用中點畫圓和Bresenham畫圓算法實現的基本圖形的繪制。能不能利用該算法,完成一些復雜圖形的生成,比如利用基本的畫圓算法繪制一個奧運五環。甚至根據畫圓算法,實現二次曲線的生成,如橢圓的生成等等。請同學們認真考慮,完成這部分的內容,上機調試。 四、思考 1.如何實現圓心為任意位置的圓的繪制; 2.兩種畫圓算法的比較。第四篇:計算機圖形學學習心得
第五篇:計算機圖形學實驗