頂點(vertexs) 圖元(primitives) 片元(fragments,又叫片斷) 像素(pixels)
階段1. 頂點 - > 圖元
幾何頂點被組合為圖元(點,線段或多邊形),然后圖元被合成片元,最后片元被轉(zhuǎn)換為幀緩存中的象素數(shù)據(jù)。
階段2. 圖元 - > 片元
圖元被分幾步轉(zhuǎn)換為片元:圖元被適當?shù)牟眉?,顏色和紋理數(shù)據(jù)也相應(yīng)作出必要的調(diào)整,相關(guān)的坐標被轉(zhuǎn)換為窗口坐標。最后,光柵化將裁剪好的圖元轉(zhuǎn)換為片元。
1) 裁剪
在裁剪時點,線段和多邊形處理略微不同。對于點,要么保留原始狀態(tài)(在裁剪體內(nèi)部),要么被裁掉(在裁剪體外部)。對于線段和多邊形來說,如果部分在裁剪體外部,則需要在裁剪點生成新的幾何頂點。對于多邊形,還需要在新增的頂點間增加完整的邊。不論裁剪了線段還是多邊形,都需要給新增幾何點賦予邊界標志、法線、顏色和紋理坐標信息。
裁剪過程時兩步:
a 應(yīng)用程序指定裁剪(Application-specific clipping),一旦組合圖元完成后,如果在程序中用glClipPlane()函數(shù)定義了任意的裁剪面,就進行裁剪。
b 視景體裁剪(View volume clipping),隨后,圖元被投影矩陣投影(進入裁剪坐標系),被相應(yīng)的視景體裁剪。投影矩陣可以由glFrustum() 或者glOrtho()定義,投影矩陣的操作和上面其他矩陣變換的操作相同。
2) 轉(zhuǎn)換到窗口坐標
裁剪坐標在轉(zhuǎn)換為窗口坐標之前,要除以規(guī)格化設(shè)備坐標(normalized device coordinates)的w值進行規(guī)范化。然后對這些規(guī)范化數(shù)據(jù)進行視口變換(viewport)計算生成窗口坐標??梢杂胓lDepthRange()和glViewport()控制視口大小,決定屏幕上顯示圖象的區(qū)域。
3) 光柵化
光柵化是將一個圖元轉(zhuǎn)變?yōu)橐粋€二維圖象(其實只是布滿平面,沒有真正的替換幀緩存區(qū))的過程。二維圖象上每個點都包含了顏色、深度和紋理數(shù)據(jù)。將該點和相關(guān)信息叫做一個片元(fragment)。(yuyu注:這就是片元和像素之間的關(guān)鍵區(qū)別,雖然兩者的直觀印象都是的像素,但是片元比像素多了許多信息,在光柵化中紋理映射之后圖元信息轉(zhuǎn)化為了像素)在這個階段,對象素繪制和位圖進行操作需要用到當前柵格位置(用glRasterPos*()定義)。正如上面討論的,三種圖元的光柵化方法是不同的,另外,象素塊和位圖也需要光柵化。
a)圖元
采用glPointSize(), glLineWidth(), glLineStipple()和 glPolygonStipple()函數(shù)可以選擇圖元的光柵化維數(shù)和模式。另外,還可以用glCullFace(), glFrontFace()和glPolygonMode()控制多邊形正反面不同的光柵化效果。
b)像素
有幾個函數(shù)實現(xiàn)像素保存和轉(zhuǎn)換。函數(shù)glPixelStore*()用于內(nèi)存中的像素是如何保存的。glPixelTransfer*() and glPixelMap*()用于像素在寫入幀緩沖區(qū)前是如何處理的。glDrawPixels()定義了一個像素矩形。用glPixelZoom()實現(xiàn)像素的縮放。
c)位圖
位圖是具有特定片元模式的0和1的矩形。每個片元有相同的相關(guān)數(shù)據(jù)??梢杂胓lBitmap()定義。
d)紋理存儲
紋理貼圖是將指定的部分紋理圖象映射到每個圖元上。每個片元(fragment)具有的紋理坐標屬性,該坐標與紋理圖象坐標對應(yīng),得到紋理圖象該位置的顏色值來修改片元的RGBA顏色,從而完成這個映射過程。用glTexImage2D()或glTexImage1D()來定義紋理圖象。glTexParameter*()和glTexEnv*()來控制紋理如何解釋和應(yīng)用到一個片元上。
e)霧
已經(jīng)光柵化的片元具有紋理貼圖修正后顏色,可以采用融合因子再融合霧顏色,該融合因子大小根據(jù)視點和片元間的距離來定。用glFog*()指定霧化顏色和融合因子。
階段3. 片元->像素
OpenGL允許光柵化生成一個片元,只要該片元通過一系列檢測就可以修改幀緩沖區(qū)中對應(yīng)像素。如果它通過測試,片元數(shù)據(jù)可以直接替換幀緩沖區(qū)中的已有值,或者和已有值合并,這取決于設(shè)置的模式。
1)像素所有權(quán)(ownership)檢測
第一個測試是判斷在幀緩沖區(qū)中的像素所對應(yīng)的某個片元是否屬于當前OpenGL上下文。如果屬于,片元進行下一個測試。如果不屬于,窗口系統(tǒng)決定是否忽略該片元,或者是否進行下一步片元操作。
2)裁剪檢測
用glScissor()函數(shù),可以定義一個任意屏幕校準矩形,在該矩形外的片元將被忽略。
3)Alpha檢測
Alpha測試只能在RGBA模式下進行,如果片元的alpha值超出一個固定參照值,片元將被忽略,這個比較函數(shù)可以用glAlphaFunc()實現(xiàn)并設(shè)定參考值。
4)模版檢測
當模版緩沖區(qū)的值超出一個參照值,模版測試將有條件的忽略該片元。這個比較函數(shù)和固定值可以用glStencilFunc()實現(xiàn)。不論圖元通過或沒有通過模版測試,模版緩沖區(qū)中的值會根據(jù)glStencilOp()函數(shù)進行修改。
5)深度檢測
當深度緩沖區(qū)的值與參照值的比較失敗,深度測試忽略該片元。GlDepthFuc()用來執(zhí)行這個比較命令。如果模版啟用,深度比較的結(jié)果會影響模版緩沖區(qū)值的更新。
6)融合
融合合并了一個片元R、G、B和A值和存儲在幀緩沖區(qū)對應(yīng)位置的這些值。融合只能在RGBA模式下實現(xiàn),它的實現(xiàn)需要片元的alpha值和對應(yīng)當前存儲象素,還需要RGB值。用glBendFun()控制,可以修改融合因子的源和目標。
7)抖動
如果啟動抖動,片元的顏色或者顏色索引采用抖動算法。這個算法只需要片元的顏色值和它的x和y坐標。
8)邏輯操作
最后,在片元和幀緩沖區(qū)對應(yīng)值之間要進行一個邏輯操作,結(jié)果將替換當前幀緩沖區(qū)的值。用glLogicOp定義想要的邏輯操作。這個邏輯操作只能在顏色索引模式下運行,而不能在RGBA模式運行。
像素
在OpenGL流水線的上個階段,片元轉(zhuǎn)換為幀緩沖區(qū)中的像素。幀緩沖區(qū)實際上是一組邏輯緩沖區(qū)——包括顏色緩沖區(qū)、深度緩沖區(qū)、模版緩沖區(qū)和累積緩沖區(qū)。顏色緩沖區(qū)包括左、前右、后左、后右和一些輔助緩存值(auxiliary buffers)??梢灾苯訌闹凶x取或者復制。對于OpenGL不同上下文,這些緩沖區(qū)可能不全
1)幀緩沖區(qū)操作
用glDrawBuffer為繪圖選擇一個顏色緩沖區(qū)。另外在預片元化(per-fragment)操作后,可以用四個不同函數(shù)保留寫入這些邏輯緩沖區(qū)的操作,glIndexMask(), glColorMask(), glDepthMask(), and glStencilMask()。glAccum()對累積緩沖區(qū)進行操作。最后glClearColor(), glClearIndex(), glClearDepth(), glClearStencil()和glClearAccum().對不同緩沖區(qū)中指定相對應(yīng)的顏色值、顏色索引值、深度值、模板值和累積值。
2)讀取和復制像素
用glReadPixel()從幀緩沖區(qū)中把像素讀到內(nèi)存中,進行各種操作,保存處理結(jié)果。另外,可以用glCopyPixel()從幀緩沖區(qū)中復制一塊象素到另一個幀混存。glReadBuffer()可以讀取和復制顏色緩沖區(qū)中的像素。
-
光柵
+關(guān)注
關(guān)注
0文章
285瀏覽量
27500 -
像素
+關(guān)注
關(guān)注
1文章
203瀏覽量
18581 -
OpenGL
+關(guān)注
關(guān)注
1文章
85瀏覽量
29243 -
函數(shù)
+關(guān)注
關(guān)注
3文章
4327瀏覽量
62569
發(fā)布評論請先 登錄
相關(guān)推薦
評論