實驗1 OpenGL初識


實驗預備知識

Windows下的OpenGL編程步驟簡單介紹詳見課程實驗教學博客-實驗准備安裝GLUT包與創建工程:

http://www.cnblogs.com/opengl/archive/2012/10/16/2726747.html

 

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.實驗代碼:

 1 #include <GL/glut.h> //需要正確安裝GLUT,安裝方法如預備知識中所述
 2 
 3 void myDisplay(void)
 4 
 5 {
 6 
 7 glClearColor(0.0, 0.0, 0.0, 0.0);
 8 glClear(GL_COLOR_BUFFER_BIT);
 9 
10 glColor3f (1.0f, 1.0f, 1.0f);
11 
12 glRectf(-0.5f, -0.5f, 0.5f, 0.5f);
13 
14 glBegin (GL_TRIANGLES);
15 
16 glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (0.0f, 1.0f);
17 
18 glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.8f, -0.5f);
19 
20 glColor3f (0.0f, 0.0f, 1.0f); glVertex2f (-0.8f, -0.5f);
21 
22 glEnd ();
23 
24 glPointSize(3);
25 
26 glBegin (GL_POINTS);
27 
28 glColor3f (1.0f, 0.0f, 0.0f); glVertex2f (-0.4f, -0.4f);
29 
30 glColor3f (0.0f, 1.0f, 0.0f); glVertex2f (0.0f, 0.0f);
31 
32 glColor3f (0.0f, 0.0f, 1.0f); glVertex2f (0.4f, 0.4f);
33 
34 glEnd ();
35 
36 glFlush();
37 }
38 int main(int argc, char *argv[])
39 {
40     glutInit(&argc, argv);
41     glutInitDisplayMode(GLUT_RGB | GLUT_SINGLE);
42     glutInitWindowPosition(100, 100);
43     glutInitWindowSize(400, 400);
44     glutCreateWindow("Hello World!");
45     glutDisplayFunc(&myDisplay);
46     glutMainLoop();
47     return 0;
48 }

 

該程序的作用是在一個黑色的窗口中央畫一個矩形、三角形和三個點,如圖A.1(a)所示。下面對各行語句進行說明:

首先,需要包含頭文件#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. 實驗提高

clip_image002clip_image004

(a)示范程序結果 (b)加三角形

圖A.1實驗1

如圖A.1(b)所示,根據示范程序,能否在原有結果基礎上添加三條直線組成三角形?

附上本實驗的VC++工程代碼(VC++2008)

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM