機械版CG 實驗1 像素點的生成

注:本博客實驗教程的配套教材爲《計算機圖形學》(徐文鵬編)已由機械工業出版社於2009年2月出版。

一.實驗總體方案

1.教學目標與基本要求

(1)       掌握教材所介紹的圖形算法的原理;

(2)       掌握通過具體的平臺實現圖形算法的方法,培養相應能力;

(3)       通過實驗培養具有開發一個基本圖形軟件包的能力。

2. 實驗平臺與考覈

實驗主要結合OpenGL設計程序實現各種課堂教學中講過的圖形算法爲主。程序設計語言主要以C/C++語言爲主,開發平臺爲Visual C++。同學們也可根據自己的基礎與興趣使用其他的編譯環境,如C++ Builder、Dev-C++等。

每次實驗前完成實驗報告的實驗目的、實驗內容、實驗原理、實驗代碼四部分並接受抽查,實驗完成後完成實驗結果、實驗體會兩部分,本次實驗課結束前提交。

3. 實驗步驟

(1) 預習教材與實驗指導相關的算法理論及原理;

(2) 仿照教材與實驗指導提供的算法,利用VC+OpenGL進行實現;

(3) 調試、編譯、運行程序,運行通過後,可考慮對程序進行修改或改進。

二. 實驗具體方案

實驗預備知識

OpenGL作爲當前主流的圖形API之一,它在一些場合具有比DirectX更優越的特性。

1)與C語言緊密結合:

OpenGL命令最初就是用C語言函數來進行描述的,對於學習過C語言的人來講,OpenGL是容易理解和學習的。如果你曾經接觸過TC的graphics.h,你會發現,使用OpenGL作圖甚至比TC更加簡單;

2)強大的可移植性:

微軟的Direct3D雖然也是十分優秀的圖形API,但它只用於Windows系統。而OpenGL不僅用於 Windows,還可以用於Unix/Linux等其它系統,它甚至在大型計算機、各種專業計算機(如:醫療用顯示設備)上都有應用。並且,OpenGL 的基本命令都做到了硬件無關,甚至是平臺無關;

3、高性能的圖形渲染:

OpenGL是一個工業標準,它的技術緊跟時代,現今各個顯卡廠家無一不對OpenGL提供強力支持,激烈的競爭中使得OpenGL性能一直領先。

總之,OpenGL是一個非常優秀的圖形軟件接口。OpenGL官方網站(英文)http://www.opengl.org/

下面將對Windows下的OpenGL編程進行簡單介紹。如下是學習OpenGL前的準備工作:

1.選擇一個編譯環境

現在Windows系統的主流編譯環境有Visual C++,C++ Builder,Dev-C++等,它們都是支持OpenGL的。但這裏我們選擇Visual C++ 作爲學習OpenGL的實驗環境。

2.安裝GLUT工具包

GLUT不是OpenGL所必須的,但它會給我們的學習帶來一定的方便,推薦安裝。Windows環境下的GLUT本地下載地址:glut-install.zip (大小約爲150k)

也可直接去官方網站下載:http://www.opengl.org/resources/libraries/glut/glutdlls37beta.zip

Windows環境下安裝GLUT的步驟:

1)將下載的壓縮包解壓,得到5個文件放到以下三個指定位置:

2)glut.h放到GL文件夾(VC6中一般是:C:\Program Files\Microsoft Visual Studio\VC98\Include\GL,VC2005中是:C:\Program Files\Microsoft Visual Studio 8\VC\Include,新建GL文件夾,再將glut.h放到GL文件夾中)。

3)glut.lib和glut32.lib放到靜態函數庫所在文件夾(VC6中一般是:C:\Program Files\Microsoft Visual Studio\VC98\Lib, VC2005中是:C:\Program Files\Microsoft Visual Studio 8\VC\Lib)。

4)glut.dll和glut32.dll放到操作系統目錄下面的system32文件夾內。(典型的位置爲:C:\Windows\System32,有些機器可能爲C:\WINNT\System32)

3.建立一個OpenGL工程

這裏以VC爲例:首先從開始->所有程序->Microsoft Visual C++ 6.0菜單中打開VC,也可單擊文件:C:\Program Files\Microsoft Visual Studio\Visual C++6\Common\MSDev98\Bin\msdev.exe打開VC,在VC中選擇File->New->Project,然後選擇Win32 Console Application,輸入一個工程名,設爲Pixel,然後按OK。

在彈出的對話框左邊點Application Settings,選擇A Simple application並勾上,選擇Finish。

然後打開工程代碼文件:Pixel.cpp,將其內容替換爲實驗示範代碼. 

實驗1 像素點的生成

1.實驗目的:

熟悉編程環境;瞭解光柵圖形顯示器的特點;瞭解計算機繪圖的特點;利用VC+OpenGL作爲開發平臺設計程序,以能夠在屏幕上生成任意一個像素點爲本實驗的結束。

2.實驗內容:

(1)       瞭解和使用VC的開發環境,理解簡單的OpenGL程序結構;

(2)       掌握OpenGL提供的基本圖形函數,尤其是生成點的函數。

3.實驗原理:

(1)基本語法

常用的程序設計語言,如C、C++、Pascal、Fortran和Java等,都支持OpenGL的開發。這裏只討論C版本下OpenGL的語法。

OpenGL基本函數均使用gl作爲函數名的前綴,如glClearColor();實用函數則使用glu作爲函數名的前綴,如gluSphere()。OpenGL基本常量的名字以GL_開頭,如GL_LINE_LOOP;實用常量的名字以GLU_開頭,如GLU_FILL。一些函數如glColor*()(定義顏色值),函數名後可以接不同的後綴以支持不同的數據類型和格式。如glColor3b(...)、glColor3d(...)、glColor3f(...)和glColor3bv(...)等,這幾個函數在功能上是相似的,只是適用於不同的數據類型和格式,其中3表示該函數帶有三個參數,b、d、f分別表示參數的類型是字節型、雙精度浮點型和單精度浮點型,v則表示這些參數是以向量形式出現的。

OpenGL定義了一些特殊標識符,如GLfloat,GLvoid。它們其實就是C中的float和void。在gl.h文件中可以看到以下定義:

……

typedef float GLfloat;

typedef void GLvoid;

……

一些基本的數據類型都有類似的定義項。

(2)程序的基本結構

OpenGL程序的基本結構可分爲三個部分:

第一部分是初始化部分。主要是設置一些OpenGL的狀態開關,如顏色模式(RGBA或ALPHA)的選擇,是否作光照處理(若有的話,還需設置光源的特性),深度檢驗,裁剪等等。這些狀態一般都用函數glEnable(...), glDisable(…)來設置,…表示特定的狀態。

第二部分設置觀察座標系下的取景模式和取景框位置大小。主要利用了三個函數:

函數void glViewport(left,top,right,bottom):設置在屏幕上的窗口大小,四個參數描述屏幕窗口四個角上的座標(以象素表示);

函數void glOrtho(left,right,bottom,top,near,far):設置投影方式爲正交投影(平行投影),其取景體積是一個各面均爲矩形的六面體;

函數void gluPerspective(fovy,aspect,zNear,zFar):設置投影方式爲透視投影,其取景體積是一個截頭錐體。

第三部分是OpenGL的主要部分,使用OpenGL的庫函數構造幾何物體對象的數學描述,包括點線面的位置和拓撲關係、幾何變換、光照處理等等。

以上三個部分是OpenGL程序的基本框架,即使移植到使用MFC的Windows程序中,也是如此。只是由於Windows自身有一套顯示方式,需要進行一些必要的改動以協調這兩種不同顯示方式。

(3)狀態機制

OpenGL的工作方式是一種狀態機制,它可以進行各種狀態或模式設置,這些狀態或模式在重新改變它們之前一直有效。例如,當前顏色就是一個狀態變量,在這個狀態改變之前,繪製的每個象素都將使用該顏色,直到當前顏色被設置爲其它顏色爲止。OpenGL中大量地使用了這種狀態機制,如顏色模式、投影模式、單雙顯示緩存區的設置、背景色的設置、光源的位置和特性等等。許多狀態變量可以通過glEnable()、glDisable()這兩個函數來設置成有效或無效狀態,如是否設置光照、是否進行深度檢測等;在被設置成有效狀態之後,絕大部分狀態變量都有一個缺省值。通常情況下,可以用下列四個函數來獲取某個狀態變量的值:glGetBooleanv()、glGetDouble()、glGetFloatv()和glGetIntegerv()。究竟選擇哪個函數應該根據所要獲得的返回值的數據類型來決定。還有些狀態變量有特殊的查詢函數,如glGetLight*()、glGetError()和glPolygonStipple()等。另外,使用glPushAttrib()和glPopAttrib()函數,可以存儲和恢復最近的狀態變量的值。只要有可能,都應該使用這些函數,因爲它們比其它查詢函數的效率更高。

4.實驗代碼:

一個簡單的OpenGL程序如下:(注意,如果需要編譯並運行,需要正確安裝GLUT,安裝方法如預備知識中所述)

#include <GL/glut.h>

void myDisplay(void)

{ glClearColor(0.0, 0.0, 0.0, 0.0);  glClear(GL_COLOR_BUFFER_BIT);

 glColor3f (1.0f, 1.0f, 1.0f);  glRectf(-0.5f, -0.5f, 0.5f, 0.5f);

 glBegin (GL_TRIANGLES);  glColor3f (1.0f, 0.0f, 0.0f);   glVertex2f (0.0f, 1.0f);  glColor3f (0.0f, 1.0f, 0.0f);   glVertex2f (0.8f, -0.5f);  glColor3f (0.0f, 0.0f, 1.0f);   glVertex2f (-0.8f, -0.5f);  glEnd ();

 glPointSize(3);  glBegin (GL_POINTS);  glColor3f (1.0f, 0.0f, 0.0f);   glVertex2f (-0.4f, -0.4f);  glColor3f (0.0f, 1.0f, 0.0f);   glVertex2f (0.0f, 0.0f);  glColor3f (0.0f, 0.0f, 1.0f);   glVertex2f (0.4f, 0.4f);  glEnd ();

 glFlush(); } int main(int argc, char *argv[]) {     glutInit(&argc, argv);     glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);     glutInitWindowPosition(100, 100);     glutInitWindowSize(400, 400);     glutCreateWindow("Hello Opengl!");     glutDisplayFunc(&myDisplay);     glutMainLoop();     return 0; }

該程序的作用是在一個黑色的窗口中央畫一個矩形、三角形和三個點。下面對各行語句進行說明:首先,需要包含頭文件#include <GL/glut.h>,這是GLUT的頭文件。本來OpenGL程序一般還要包含<GL/gl.h>和<GL/glu.h>,但GLUT的頭文件中已經自動將這兩個文件包含了,不必再次包含;

然後看main函數。int main(int argc, char *argv[]),這個是帶命令行參數的main函數。注意main函數中的各語句,除了最後的return之外,其餘全部以glut開頭。這種以glut開頭的函數都是GLUT工具包所提供的函數,下面對用到的幾個函數進行介紹;

1)glutInit,對GLUT進行初始化,這個函數必須在其它的GLUT使用之前調用一次。其格式比較固定,一般都是glutInit(&argc, argv)就行;

2) glutInitDisplayMode,設置顯示方式,其中GLUT_RGB表示使用RGB顏色,與之對應的還有GLUT_INDEX(表示使用索引顏色)。GLUT_SINGLE表示使用單緩衝,與之對應的還有GLUT_DOUBLE(使用雙緩衝)。更多信息,以後的實驗教程會有講解介紹;

3) glutInitWindowPosition,設置窗口在屏幕中的位置;

4) glutInitWindowSize,設置窗口的大小;

5) glutCreateWindow,根據前述設置的信息創建窗口。參數將被作爲窗口的標題。注意:窗口被創建後,並不立即顯示到屏幕上。需要調用glutMainLoop才能看到窗口;

6) glutDisplayFunc,設置一個函數,當需要進行畫圖時,這個函數就會被調用。(暫且這樣理解);

7) glutMainLoop,進行一個消息循環。(現在只需知道這個函數可以顯示窗口,並且等待窗口關閉後纔會返回。)

在glutDisplayFunc函數中,我們設置了“當需要畫圖時,請調用myDisplay函數”。於是myDisplay函數就用來畫圖。觀察myDisplay中的三個函數調用,發現它們都以gl開頭。這種以gl開頭的函數都是OpenGL的標準函數,下面對用到的函數進行介紹:

1) glClearColor(0.0, 0.0, 0.0, 0.0) :將清空顏色設爲黑色(爲什麼會有四個參數?);

2) glClear(GL_COLOR_BUFFER_BIT):將窗口的背景設置爲當前清空顏色;

3) glRectf,畫一個矩形。四個參數分別表示了位於對角線上的兩個點的橫、縱座標;

4) glFlush,保證前面的OpenGL命令立即執行(而不是讓它們在緩衝區中等待)。 

5. 思考題 左圖是示範程序的結果,能否在原有結果基礎上添加三條直線組成新的三角形?(如右圖所示) 請在實驗報告的實驗結果將改動結果寫出.

                          示範程序結果                                                                             需要顯示的結果 附:北大計算機圖形學課程教學網站: http://graphics.pku.edu.cn/courses/CG/index.htm

發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章