黄色网页视频 I 影音先锋日日狠狠久久 I 秋霞午夜毛片 I 秋霞一二三区 I 国产成人片无码视频 I 国产 精品 自在自线 I av免费观看网站 I 日本精品久久久久中文字幕5 I 91看视频 I 看全色黄大色黄女片18 I 精品不卡一区 I 亚洲最新精品 I 欧美 激情 在线 I 人妻少妇精品久久 I 国产99视频精品免费专区 I 欧美影院 I 欧美精品在欧美一区二区少妇 I av大片网站 I 国产精品黄色片 I 888久久 I 狠狠干最新 I 看看黄色一级片 I 黄色精品久久 I 三级av在线 I 69色综合 I 国产日韩欧美91 I 亚洲精品偷拍 I 激情小说亚洲图片 I 久久国产视频精品 I 国产综合精品一区二区三区 I 色婷婷国产 I 最新成人av在线 I 国产私拍精品 I 日韩成人影音 I 日日夜夜天天综合

Win32 OpenGL編程(3) 基本圖元(點(diǎn),直線,多邊

系統(tǒng) 2557 0

Win32 OpenGL 編程 ( 3 ) 基本圖元(點(diǎn),直線,多邊形)的繪制

write by 九天雁翎 (JTianLing) -- blog.csdn.net/vagrxie

討論新聞組及文件

一、 提要

在前面兩篇相關(guān)文章

Win32 OpenGL 編程(1)Win32下的OpenGL編程必須步驟

Win32 OpenGL編程(2) 尋找缺失的OpenGL函數(shù)

中,我們已經(jīng)建立了一個較為全面的 Win32 OpenGL 編程環(huán)境及一個簡單的框架,并且,實(shí)際上掌握了 OpenGL Windows 下與 Win32 窗口交互的方法,在此基礎(chǔ)上,總算是可以正式進(jìn)行一些 OpenGL 相關(guān)知識的學(xué)習(xí),前面的那些也就算是熱身。本文的目的是將 OpenGL 中基本圖元(點(diǎn),線,多邊形)的繪制大概的講解一遍,最后可以組合的使用這些技術(shù)用 OpenGL 完成較為復(fù)雜的 2D 圖形。

二、 基本圖元相關(guān)概念

首先講講相關(guān)的概念,在 OpenGL 中,即使是復(fù)雜的圖形,實(shí)際上也是由一些非常基本的圖元組成,即點(diǎn),直線,多邊形,多邊形中用的較多的又是三角形和矩形。在數(shù)學(xué)中,兩點(diǎn)確定一條直線,三點(diǎn)確定一個三角形和一個面,同一個面上的四個點(diǎn)確定一個四邊形。。。。。。在 OpenGL 中也大致的利用此方式來確定直線和多邊形,也就是說,當(dāng)你想畫一個直線或者一個多邊形的時候,只需要告訴 OpenGL 能確定此直線或者多邊形的點(diǎn)即可。用參考 2 中的描述是:“在 OpenGL 中,所有的幾何物體最終都描述成一組有序的頂點(diǎn)”。有此基本的概念后就可以看下面的例子了。

三、 OpenGL Hello World 示例分析

這里的 Hello World 程序指的是一個利用 OpenGL 完成的矩形繪制程序,相對于在系列文章 1 中的 Win32 OpenGL 編程框架,簡化了很多東西,只剩下最最基本的 OpenGL 元素,但也是一個完善的 OpenGL 示例了。此示例顯示的是一個白色的矩形,運(yùn)行效果如附圖 1 ,完整代碼見我博客代碼的 2009-10-12/SimpleRectangle 工程,具體下載及查看方法見本文最后的說明。

此示例 OpenGL 相關(guān)的主要就是兩部分。

//OpenGL 初始化開始

void SceneInit ( int w , int h )

{

}

// 這里進(jìn)行所有的繪圖工作

void SceneShow ( GLvoid )

{

glClear ( GL_COLOR_BUFFER_BIT );

glBegin ( GL_QUADS );

glVertex3f (-0.5, -0.5, 0.0);

glVertex3f (0.5, -0.5, 0.0);

glVertex3f (0.5, 0.5, 0.0);

glVertex3f (-0.5, 0.5, 0.0);

glEnd ();

glFlush ();

}

我們下面從 OpenGL 的角度來分析此程序。作為 HelloWorld 級的程序,我簡化了很多東西,首先 OpenGL 的初始化省略了,用的都是 OpenGL 的默認(rèn)值,具體有哪些,后面一步一步說。以下是按步驟說明每個 OpenGL 函數(shù)。

1. glClear

OpenGL 參考手冊 :

glClear takes a single argument that is the bitwise OR of several values indicating which buffer is to be cleared.

GL_COLOR_BUFFER_BIT Indicates the buffers currently enabled for color writing.

作用是清除顏色緩沖區(qū)。類似于我們使用一塊新申請的內(nèi)存時先用 memset/ZeroMemory 去清零一下,用這樣的 Clear 操作為我們需要使用的顏色緩沖區(qū) (Color Buffer) 清零一下。假如沒有這樣的操作,以前留在顯存 / 內(nèi)存 ( 不確定 ) 中的值會影響我們的操作,并且,這樣的問題往往是非常難以調(diào)試和發(fā)現(xiàn)的,這一點(diǎn)大家可以嘗試一下。

2. glBegin glEnd

OpenGL 參考手冊 :

glBegin, glEnd - delimit the vertices of a primitive or a group of like primitives

OpenGL 代碼的主體部分是:

glBegin ( GL_QUADS );

glVertex3f (-0.5, -0.5, 0.0);

glVertex3f (0.5, -0.5, 0.0);

glVertex3f (0.5, 0.5, 0.0);

glVertex3f (-0.5, 0.5, 0.0);

glEnd ();

glBegin glEnd 很明顯是一對, 標(biāo)志著一組 OpenGL 操作的開始和結(jié)束。 并且在參數(shù)中告訴了 OpenGL 下面的操作是針對什么圖形進(jìn)行的,此例中 GL_QUADS 是表示四邊形。事實(shí)上還有很多其他的參數(shù)來表示各類圖形,在《 OpenGL Programming Guide 》的 此頁 Figure 2-7 : Geometric Primitive Types 一圖形象的說明了各個參數(shù)的作用。

3. glVertex *

glVertex3f 就是在 基本圖元相關(guān)概念 一節(jié)提到的 OpenGL 中確定頂點(diǎn)的函數(shù)。簡而言之,上面的 4 glVertex3f 確定了矩形的 4 個頂點(diǎn)。(注意順序)然后, OpenGL 就會自動根據(jù) glBegin 指定的參數(shù)去完成相關(guān)的繪制任務(wù)了, 此例中 GL_QUADS 是表示四邊形,所以最后的效果是一個矩形,實(shí)際的其他參數(shù)讀者可以自己嘗試一下。

4. OpenGL 默認(rèn)坐標(biāo)系

我們再看一下 glVertex* 指定頂點(diǎn)的代碼:

glVertex3f (-0.5, -0.5, 0.0);

glVertex3f (0.5, -0.5, 0.0);

glVertex3f (0.5, 0.5, 0.0);

glVertex3f (-0.5, 0.5, 0.0);

為什么上述就指定了一個矩形的四個頂點(diǎn)呢?需要說明的是,在 OpenGL 中默認(rèn)坐標(biāo)體系與 Windows 中常用的不同, Windows 中常用的坐標(biāo)體系(僅 2D )是用戶區(qū)的左上角為坐標(biāo)原點(diǎn),即 (0.0,0.0) 點(diǎn),右為坐標(biāo)軸的 X 軸正方向,下為 Y 軸正方向, OpenGL 中的坐標(biāo)軸( 3D )默認(rèn)以客戶區(qū)中心點(diǎn)為坐標(biāo)原點(diǎn)( 0.0,0.0,0.0 ),右為坐標(biāo)軸的 X 軸正方向,上為 Y 軸正方向,垂直指出屏幕的方向?yàn)? Z 軸正方向。長度定義是將客戶區(qū)范圍為按單位長度定義,即整個客戶區(qū)恰好是 (-1,-1) (左下)到 (1,1) (右上)。附圖 2 是一個上述示例程序附上 OpenGL 的平面坐標(biāo)系的圖,也可以作為 OpenGL 默認(rèn)坐標(biāo)系的參考圖。

5. OpenGL 函數(shù)命名

這里順面介紹一下 OpenGL 函數(shù)的命名規(guī)范,因?yàn)? C 語言天生的弱點(diǎn)及豐富的數(shù)據(jù)類型,在 OpenGL 中凡是牽涉到與參數(shù)數(shù)量和數(shù)據(jù)類型相關(guān)的函數(shù),一般的命名方式都是 xxxx[n][t]

xxxx 表示函數(shù)的意義, [t] 用于表示此函數(shù)對應(yīng)的類型。一般用單個的字母表示參數(shù)的類型, s 表示 16 位整數(shù)( OpenGL 中將這個類型定義為 GLshort ), i 表示 32 位整數(shù)( OpenGL 中將這個類型定義為 GLint GLsizei ), f 表示 32 位浮點(diǎn)數(shù)( OpenGL 中將這個類型定義為 GLfloat ), d 表示 64 位浮點(diǎn)數(shù)( OpenGL 中將這個類型定義為 GLdouble )。此例中使用的是 32 位浮點(diǎn)數(shù),所以是 f 。這是 C 語言沒有函數(shù)重載機(jī)制的天生弱點(diǎn)導(dǎo)致的扭曲應(yīng)對方案。(用 C++ 就不需要這么麻煩了)

然后是數(shù)字,因?yàn)橥瑯拥脑颍? C 語言中一個同樣意義的函數(shù)不能同時有不同個數(shù)的參數(shù),所以 OpenGL 用一個數(shù)字來表示參數(shù)的個數(shù),此例中是 3 ,表示以 3 個參數(shù)(即點(diǎn)的 X,Y,Z 坐標(biāo))來表示頂點(diǎn)。(事實(shí)上還有 glVertex2* glVertex4*

比如此例中,用如下代碼效果是一樣的:

glVertex2f (-0.5, -0.5);

glVertex2f (0.5, -0.5);

glVertex2f (0.5, 0.5) ;

glVertex2f (-0.5, 0.5);

glVertex2f 中, Z 軸默認(rèn)為 0.

這里我依照參考 2 的用法,以 * 作為通配符來表示一組函數(shù), * 既可以表示代表參數(shù)數(shù)量的數(shù)字也可以表示代表類型的字母。

6. glFlush

OpenGL 參考手冊 :

glFlush - force execution of GL commands in finite time

說白了就是強(qiáng)制執(zhí)行已經(jīng)指定的 OpenGL 命令,與 fflush 命名類似作用也類似。

7. 小結(jié)

以上的 5 OpenGL 函數(shù)就構(gòu)成了一個基本的 OpenGL 程序(不包括模板中使用的那些),由 glClear 清空顏色緩沖區(qū)獲得干凈的環(huán)境,由 glBegin 指定開始一組頂點(diǎn)操作的開始,并確認(rèn)繪制圖形,由 glVertex* 指定頂點(diǎn),由 glEnd 表示操作結(jié)束,由 glFlush 強(qiáng)制開始繪圖。運(yùn)行效果如附圖 1

四、 基本圖元

事實(shí)上,上一節(jié)已經(jīng)包含了所有的知識,各個圖元在 OpenGL 中繪制方式的不同僅僅在于 glBegin 的參數(shù)不同而已,這里將基本圖元簡單介紹一下。

1. 點(diǎn)

點(diǎn)是最常用的圖元之一了,而且所有的圖像都可以看做是由點(diǎn)構(gòu)成的,事實(shí)上屏幕也就是由一個一個像素點(diǎn)構(gòu)成了圖像:)

畫點(diǎn)的方式是使用 GL_POINTS 為參數(shù)調(diào)用 glBegin 。那么,每一個 glVertex* 指定頂點(diǎn)就會繪制成一個單獨(dú)的點(diǎn)。點(diǎn)的默認(rèn)大小為 1 個像素,可以通過 glPointSize 函數(shù)來改變點(diǎn)的大小,在點(diǎn)比較大并且沒有開啟抗鋸齒時,是按照一個正方形來繪制的。比如上例中,僅僅將 GL_QUADS 換成 GL_POINTS ,將是繪制上述矩形的 4 個頂點(diǎn),為了截圖效果顯著,調(diào)用 glPointSize 將點(diǎn)的大小改為 20 。如下代碼:

// 這里進(jìn)行所有的繪圖工作

void SceneShow ( GLvoid )

{

glClear ( GL_COLOR_BUFFER_BIT );

glPointSize (20);

glBegin ( GL_POINTS );

glVertex3f (-0.5, -0.5, 0.0);

glVertex3f (0.5, -0.5, 0.0);

glVertex3f (0.5, 0.5, 0.0);

glVertex3f (-0.5, 0.5, 0.0);

glEnd ();

glFlush ();

}

效果如附圖 3 所示。

光是點(diǎn)也可以做很多有趣的應(yīng)用, Windows 的屏保模擬星空即是其一,事實(shí)上,在原來學(xué)習(xí)簡單的圖形編程時,我用多種語言嘗試了用點(diǎn)做一些有意思的東西。見簡單圖形編程學(xué)習(xí)系列:

簡單圖形編程的學(xué)習(xí)( 2 --- 點(diǎn) (Qt 實(shí)現(xiàn) )

簡單圖形編程的學(xué)習(xí)( 2 --- 點(diǎn) (Windows GDI 實(shí)現(xiàn) )

簡單圖形編程的學(xué)習(xí)( 2 --- 點(diǎn) (small basic 實(shí)現(xiàn) )

其中點(diǎn)與文字結(jié)合形成的那個星空文字效果我是印象深刻,我一直將其作為“簡單的編程技術(shù) + 創(chuàng)意”也能很強(qiáng)大的例子。

2. 直線

直線也是很基礎(chǔ)的東西了,但是 OpenGL 中的直線與數(shù)學(xué)概念上有些區(qū)別,不知道外國的那些專家在命名時為啥亂了,其實(shí) OpenGL 中的直線與數(shù)學(xué)中的線段概念一致,有兩個端點(diǎn)確認(rèn)長度。事實(shí)上,在 OpenGL 繪制中,指定的也就是線段的兩個端點(diǎn)。用 GL_LINES 調(diào)用 glBegin 時,表示繪制的是直線。默認(rèn)情況下寬度為一個像素,同樣, OpenGL 也提供了函數(shù) glLineWidth 用以改變直線的寬度。比如上例中,僅僅將 GL_QUADS 換成 GL_LINES 將是兩條平行的直線,并用 glLineWidth 將直線寬度改為 5 ,如下代碼:

// 這里進(jìn)行所有的繪圖工作

void SceneShow ( GLvoid )

{

glClear ( GL_COLOR_BUFFER_BIT );

glLineWidth (5);

glBegin ( GL_LINES );

glVertex3f (-0.5, -0.5, 0.0);

glVertex3f (0.5, -0.5, 0.0);

glVertex3f (0.5, 0.5, 0.0);

glVertex3f (-0.5, 0.5, 0.0);

glEnd ();

glFlush ();

}

運(yùn)行效果如附圖 4 所示。

直線的應(yīng)用也是非常廣泛的,還記得 Windows 的屏保中的變幻線嗎?千變?nèi)f變,無論多么絢爛的效果,其實(shí)也僅僅是一條條變化的線段而已。

3. 多邊形

其實(shí)可以將多邊形看成是從點(diǎn)到線到面的一種擴(kuò)展,這里的面自然也是有范圍的,那么就成了多邊形了,在繪制圖形中用的最多的是三角形,因?yàn)槿切慰隙ㄔ谕粋€面上,這樣可以簡化很多計(jì)算的處理。 GL_TRIANGLES 調(diào)用 glBegin 表示開始繪制三角形。然后還有 GL_QUADS 表示四邊形(上例中的用法), GL_POLYGON 表示多邊形(必須是凸的)。

4. 小結(jié)

其實(shí)除了上面講到的那些參數(shù),還有一些額外的參數(shù),比如 GL_LINE_STRIP,GL_TRIANGLES_STRIP 等,表示繪制的時候繪制一些列連續(xù)的圖形,這些參數(shù)用文字解釋起來不夠形象,還是推薦參考 OpenGL Programming Guide 》的 此頁 Figure 2-7 : Geometric Primitive Types 一圖,此圖形象的展示了各個參數(shù)時對點(diǎn)的解釋方式和順序。在此圖的下面,還有個表總結(jié)了一下各個參數(shù)的作用。

在一個 glBegin glEnd 對中可以連續(xù)的制定多個頂點(diǎn),甚至超出你指定的圖形的數(shù)目,比如繪制三角形時可以指定 6 個點(diǎn),那么此時,將會繪制兩個三角形而不是一個,這樣而當(dāng)指定 4 5 個點(diǎn)時用 GL_TRIANGLES 參數(shù)時將會丟棄,用 GL_TRIANGLE_STRIP 參數(shù)時將會連續(xù)繪制兩個三角形,具體的解釋方法也是要看 glBegin 參數(shù)的,建議還是參考上述圖片。

五、 參考資料

1. OpenGL Reference Manual 》, OpenGL 參考手冊

2. OpenGL 編程指南》(《 OpenGL Programming Guide 》), Dave Shreiner Mason Woo Jackie Neider Tom Davis 著,徐波譯,機(jī)械工業(yè)出版社

3. Nehe OpenGL Tutorials 》, Nehe 著,在 http://nehe.gamedev.net/ 上可以找到教程及相關(guān)的代碼下載,(有 PDF 版本教程下載) Nehe 自己還做了一個面向?qū)ο蟮目蚣埽鳛檠菔境绦騺碚f,這樣的框架非常合適。也有 中文版 ,各取所需吧。

4. OpenGL 入門學(xué)習(xí)》 eastcowboy 著,這是我在網(wǎng)上找到的一個比較好的教程,較為完善,而且非常通俗。這是第一篇的地址: http://bbs.pfan.cn/post-184355.html

六、 系列其他文章

1. Win32 OpenGL 編程(1)Win32下的OpenGL編程必須步驟

2. Win32 OpenGL編程(2) 尋找缺失的OpenGL函數(shù)

七、 最后說明

本文中所有代碼(如果有的話)都能用 Mercurial Google Code 中下載。

文章以博文發(fā)表的日期分目錄存放,下載地址見:

http://code.google.com/p/jtianling/source/checkout?repo=blog-sample-code

或者直接使用 Mercurial 克隆下列庫:

https://blog-sample-code.jtianling.googlecode.com/hg/

Mercurial 使用方法見《 分布式的,新一代 版本控制系統(tǒng) Mercurial 的介紹及簡要入門

八、 附圖

1. 1 SimpleRectangle

Win32 OpenGL編程(3) 基本圖元(點(diǎn),直線,多邊形)的繪制

圖2 SimpleRectangle with coordinate

Win32 OpenGL編程(3) 基本圖元(點(diǎn),直線,多邊形)的繪制

圖3 SimplePoints

Win32 OpenGL編程(3) 基本圖元(點(diǎn),直線,多邊形)的繪制

圖4 SimpleLines

Win32 OpenGL編程(3) 基本圖元(點(diǎn),直線,多邊形)的繪制

write by 九天雁翎 (JTianLing) -- blog.csdn.net/vagrxie

Win32 OpenGL編程(3) 基本圖元(點(diǎn),直線,多邊形)的繪制


更多文章、技術(shù)交流、商務(wù)合作、聯(lián)系博主

微信掃碼或搜索:z360901061

微信掃一掃加我為好友

QQ號聯(lián)系: 360901061

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描下面二維碼支持博主2元、5元、10元、20元等您想捐的金額吧,狠狠點(diǎn)擊下面給點(diǎn)支持吧,站長非常感激您!手機(jī)微信長按不能支付解決辦法:請將微信支付二維碼保存到相冊,切換到微信,然后點(diǎn)擊微信右上角掃一掃功能,選擇支付二維碼完成支付。

【本文對您有幫助就好】

您的支持是博主寫作最大的動力,如果您喜歡我的文章,感覺我的文章對您有幫助,請用微信掃描上面二維碼支持博主2元、5元、10元、自定義金額等您想捐的金額吧,站長會非常 感謝您的哦!!!

發(fā)表我的評論
最新評論 總共0條評論