一、基礎(chǔ)圖形管線
渲染管線(rendering pipeline),它是一系列數(shù)據(jù)處理過(guò)程,并且將應(yīng)用程序的數(shù)據(jù)轉(zhuǎn)換到最終渲染的圖像。下圖是OpenGL 4.3 版本的管線。


OpenGL 中的 圖元 只不過(guò)是頂點(diǎn)的集合以預(yù)定義的方式結(jié)合在一起罷了。
通過(guò)最近學(xué)習(xí) OpenGL 的藍(lán)寶書(shū)(《OpenGL超級(jí)寶典》),學(xué)到了基礎(chǔ)渲染這塊,為了加深理解,按照書(shū)中優(yōu)化了一下渲染管線的流程圖,并在圖中添加上了翻譯和自己的理解,加深自己的印象并幫助更多學(xué)習(xí) OpenGL 的朋友們更好的學(xué)習(xí)。
OpenGL渲染管線簡(jiǎn)化流程圖:

1、客戶(hù)端-服務(wù)器
管線上半部分是客戶(hù)端,下半部分是服務(wù)器。就 OpenGL 而言,客戶(hù)端是存儲(chǔ)在 CPU 存儲(chǔ)器中的,驅(qū)動(dòng)程序?qū)秩久钆c數(shù)據(jù)組合起來(lái)發(fā)給服務(wù)器執(zhí)行。
服務(wù)器和客戶(hù)端在功能上是異步的??蛻?hù)端不斷的將數(shù)據(jù)和命令組合在一起送入緩沖區(qū),緩沖區(qū)再發(fā)送到服務(wù)器執(zhí)行。
2、著色器
上圖中最大的框代表的是 頂點(diǎn)著色器 和 片元著色器。著色器是使用GLSL編寫(xiě)的程序。
頂點(diǎn)著色器:頂點(diǎn)著色器處理從客戶(hù)端輸入的數(shù)據(jù),用數(shù)學(xué)運(yùn)算來(lái)計(jì)算光照效果、位移、顏色值等。有幾個(gè)頂點(diǎn),頂點(diǎn)著色器就要執(zhí)行幾次。
上圖中的 圖元組合(Primitive Assembly)框圖意在說(shuō)明3個(gè)頂點(diǎn)已經(jīng)組合在了一起。
片元著色器:片元著色器來(lái)計(jì)算片元的最終顏色(盡管在下一個(gè)階段(逐片元的操作)時(shí)可能還會(huì)改變顏色一次)和它的深度值。在這里我們會(huì)使用紋理映射的方式,對(duì)頂點(diǎn)處理階段所計(jì)算的顏色值進(jìn)行補(bǔ)充。如果我們覺(jué)得不應(yīng)該繼續(xù)繪制某個(gè)片元,在片元著色器中還可以終止這個(gè)片元的處理,這一步叫做片元的丟棄(discard)。
頂點(diǎn)的著色器和片元著色器之間的區(qū)別: 頂點(diǎn)著色(包括細(xì)分和幾何著色)決定了一個(gè)圖元應(yīng)該位于屏幕的什么位置,而片元著色使用這些信息來(lái)決定某個(gè)片元的顏色應(yīng)該是什么。
著色器的渲染:
頂點(diǎn)著色器(必要)
細(xì)分著色器(可選)
幾何著色器(可選)
片元著色器(必要)
3、三種向OpenGL 著色器傳遞渲染數(shù)據(jù)的?法
屬性:就是對(duì)?個(gè)頂點(diǎn)都要作出改變的數(shù)據(jù)元素。實(shí)際上,頂點(diǎn)位置本身就是一個(gè)屬性.。屬性可以是浮點(diǎn)類(lèi)型,整型,布爾類(lèi)型等。
Uniform值:通過(guò)設(shè)置 Uniform 變量就緊接著發(fā)送一個(gè)圖元批次處理命令。Uniform 變量實(shí)際上可以無(wú)限次的使?。 設(shè)置一個(gè)應(yīng)用于整個(gè)表?面的單個(gè)顏色值,還可也是一個(gè)時(shí)間值。
使用下面的函數(shù):
// Use a stock shader, and pass in the parameters needed
GLint UseStockShader(GLT_STOCK_SHADER nShaderID, ...);
傳遞不用的 Uniform 參數(shù)可以使用不同的存儲(chǔ)著色器:
首先定義一個(gè)顏色黑色 vBlack:
GLfloat vBlack[] = { 0.0f, 0.0f, 0.0f, 1.0f };
聲明一個(gè)全局的存儲(chǔ)著色器變量 shaderManager:
GLShaderManager shaderManager;
shaderManager.UseStockShader(GLT_SHADER_FLAT, transformPipeline.GetModelViewProjectionMatrix(), vBlack);
//使用 單位著色器
//參數(shù)1:簡(jiǎn)單的使用默認(rèn)笛卡爾坐標(biāo)系(-1,1),所有片段都應(yīng)用一種顏色。GLT_SHADER_IDENTITY
//參數(shù)2:著色器顏色
shaderManager.UseStockShader(GLT_SHADER_IDENTITY, vGreen);
GLShaderManger::UseStockShader(GLT_SHADER_IDENTITY,GLfloat mvp[16],GLfloat vColor[4])
紋理:對(duì)紋理進(jìn)行采樣和篩選。紋理數(shù)據(jù)的作用不僅僅是表現(xiàn)圖形。很多圖形文件格式都是以無(wú)符號(hào)字節(jié)形式對(duì)顏色分量進(jìn)行存儲(chǔ)的,但我們?nèi)匀豢梢栽O(shè)置浮點(diǎn)紋理。這就是說(shuō),任何大型浮點(diǎn)數(shù)據(jù)塊(例如消耗資源很大的函數(shù)的大型查詢(xún)表)都可以通過(guò)這種方式傳遞給著色器。
4、使用存儲(chǔ)著色器
在OpenGL 核心框架中,并沒(méi)提供任何內(nèi)建渲染管線,在提交一個(gè)幾何圖形進(jìn)行渲染之前,必須實(shí)現(xiàn)一個(gè)著色器。著色器由GLTools 的 C++ 類(lèi) GLShaderManager 管理。他們能夠滿(mǎn)足進(jìn)行基本渲染的基本要求,要求不高的程序員,這些存儲(chǔ)著色器已經(jīng)足以滿(mǎn)足他們的需求。但隨著時(shí)間和經(jīng)驗(yàn)的提升,大部分開(kāi)發(fā)者可能不滿(mǎn)足于此,會(huì)著手去寫(xiě)著色器,手寫(xiě)的我會(huì)在以后的文章里再寫(xiě)出來(lái)。
4.1著色器的使用
1)GLShaderManager 的初始化:
GLShaderManager shaderManager;
shaderManager.InitializeStockShaders();
2)GLShaderManager 屬性:
存儲(chǔ)著色器為每個(gè)變量都使用一致的內(nèi)部變量命名規(guī)則和相同的屬性槽(Attribute Slot)。下表列出了這些屬性:
表-GLShaderManager 預(yù)定義的標(biāo)識(shí)符
| 標(biāo)識(shí)符 | 描述 |
|---|---|
| GLT_ATTRIBUTE_VERTEX | 3分量(x, y, z)頂點(diǎn)位置 |
| GLT_ATTRIBUTE_COLOR | 4分量(r, g, b, a)顏色值 |
| GLT_ATTRIBUTE_NORMAL | 3分量(x, y, z)表面法線 |
| GLT_ATTRIBUTE_TEXTURE0 | 第一對(duì) 2 分量(s ,t)紋理坐標(biāo) |
| GLT_ATTRIBUTE_TEXTURE1 | 第二對(duì) 2 分量(s ,t)紋理坐標(biāo) |
4.2 GLShanderManager 的 uniform 值
一般情況,要對(duì)幾何圖形進(jìn)行渲染,我們需要為讀寫(xiě)遞交屬性矩陣,首先要綁定到我們想要使用的著色程序上,并提供程序的 Uniform 值。GLShanderManager 類(lèi)可以(暫時(shí))為我們完成這項(xiàng)工作。
useStockShader 函數(shù)會(huì)選擇一個(gè)存儲(chǔ)著色器并提供這個(gè)著色器的 Uniform 值,這些工作通過(guò)一次函數(shù)調(diào)用就能完成:
GLShaderManager::UseStockShader(GLenum shader, ... ...);
在 C 語(yǔ)言(或 C++ 語(yǔ)言)中,......表示函數(shù)接受一個(gè)可變的參數(shù)數(shù)量。就這個(gè)函數(shù)本身而言,它根據(jù)我們選擇的著色器,從堆棧中提取正確的參數(shù),這些參數(shù)就是特定著色器要求的 Uniform 值。
(1) 單位(Identity)著色器 GLT_SHADER_IDENTITY
參數(shù)1:?jiǎn)挝恢?參數(shù)2:顏色值
GLShaderManager::UseStockShader(GLT_SHADER_IDENTITY, GLfoat vColor[4]);
單位(Identity)著色器: 只是簡(jiǎn)單地使用默認(rèn)的笛卡爾坐標(biāo)系(坐標(biāo)范圍-1.0~1.0)。所有片段都應(yīng)用同一種顏色,結(jié)合圖形為實(shí)心和未渲染的。這種著色器只使用一個(gè)屬性
GLT_ATTRIBUTE_VERTEX。vColor參數(shù)包含了要求的顏色。
(2) 平面(Flat)著色器 GLT_SHADER_FLAT
參數(shù)1:平面著色器
參數(shù)2:允許變化的4*4矩陣
參數(shù)3:顏色值
GLShaderManager::UseStockShader(GLT_SHADER_FLAT, GLfoat mvp[16], GLfloat vColor[4]);
平面(Flat)著色器:將單位著色器進(jìn)行了擴(kuò)展,允許為集合圖形變換指定一個(gè) 4 x 4 的變換矩陣。經(jīng)常被稱(chēng)作“模型師徒投影矩陣”。這種著色器只使用一個(gè)屬性
GLT_ATTRIBUTE_VERTEX。
(3) 上色(Shaded)著色器 GLT_SHADER_SHADED
GLShaderManager::UseStockShader(GLT_SHADER_SHADED, GLfoat mvp[16]);
上色(Shaded)著色器:唯一的 Uniform 值就是在幾何圖形中應(yīng)用的變換矩陣。GLT_ATTRIBUTE_VERTEX 和 GLT_ATTRIBUTE_COLOR 在這種著色器中都會(huì)使用。顏色值將被平滑地插入頂點(diǎn)之間(稱(chēng)為平滑著色)。
(4) 默認(rèn)光源著色器 GLT_SHADER_DEFAULT_LIGHT
參數(shù)1:默認(rèn)光源著色器
參數(shù)2:模型視圖矩陣
參數(shù)3:投影矩陣
參數(shù)4:顏色值
GLShaderManager::UseStockShader(GLT_SHADER_DEFAULT_LIGHT, GLfoat mvMatrix[16], GLfloat pMatrix[16], GLfloat vColor[4]);
默認(rèn)光源著色器:這種著色器使對(duì)象產(chǎn)生陰影和光照的效果。需要模型視圖矩陣、投影矩陣和作為基本色的顏色值等 Uniform 值。所需的屬性有 GLT_ATTRIBUTE_VERTEX(頂點(diǎn)分量)和 GLT_ATTRIBUTE_NORMAL(表面法線)。
(5) 點(diǎn)光源著色器 GLT_SHADER_POINT_LIGHT_DIFF
參數(shù)1:點(diǎn)光源著色器
參數(shù)2:模型視圖矩陣
參數(shù)3:投影矩陣
參數(shù)4:視點(diǎn)坐標(biāo)系中的光源位置
參數(shù)5:顏色值
GLShaderManager::UseStockShader(GLT_SHADER_POINT_LIGHT_DIFF, GLfoat mvMatrix[16], GLfloat pMatrix[16], GLfloat vLightPos[3], GLfloat vColor[4]);
點(diǎn)光源著色器:和默認(rèn)光源著色器很相似,但光源位置可能是待定的。接受 4 個(gè) Uniform 值,即模型視圖矩陣、投影矩陣、視點(diǎn)坐標(biāo)系中的光源位置和對(duì)象的基本漫反射顏色。同樣所需的屬性有 GLT_ATTRIBUTE_VERTEX(頂點(diǎn)分量)和 GLT_ATTRIBUTE_NORMAL(表面法線)。
(6) 紋理替換矩陣 GLT_SHADER_TEXTURE_REPLACE
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_REPLACE, GLfoat mvMatrix[16], GLint nTextureUnit);
紋理替換矩陣:著色器通過(guò)給定的模型視圖投影矩陣,使用綁定到 nTextureUnit(紋理單元) 指定的紋理單元的紋理對(duì)幾何圖形進(jìn)行變換。片段顏色是從紋理樣本中直接獲取的。所需的屬性有 GLT_ATTRIBUTE_VERTEX(頂點(diǎn)分量)和 GLT_ATTRIBUTE_NORMAL(表面法線)。
(7) 紋理調(diào)整著色器 GLT_SHADER_TEXTURE_MODULATE
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_MODULATE, GLfoat mvMatrix[16], GLfloat vColor, GLint nTextureUnit);
紋理調(diào)整著色器:這種著色器將一個(gè)基本色乘以一個(gè)取自紋理單元 nTextureUnit 的紋理。所需的屬性有 GLT_ATTRIBUTE_VERTEX(頂點(diǎn)分量)和 GLT_ATTRIBUTE_TEXTURE0(紋理坐標(biāo))。
(8) 紋理光源著色器 GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF
參數(shù)1:紋理光源著色器
參數(shù)2:模型視圖矩陣
參數(shù)3:投影矩陣
參數(shù)4:視點(diǎn)坐標(biāo)系中的光源位置
參數(shù)5:幾何圖形的基本色
參數(shù)6:將要使用的紋理單元
GLShaderManager::UseStockShader(GLT_SHADER_TEXTURE_POINT_LIGHT_DIFF, GLfloat mvMatrix, GLfoat mvMatrix[16], GLfloat vLightPos[3], GLfloat vBaseColor[4], GLint nTextureUnit);
紋理光源著色器:這種著色器將一個(gè)紋理通過(guò)漫反射照明計(jì)算進(jìn)行調(diào)整(相乘),光線在視覺(jué)空間中的位置是給定的。這種著色器接受 5 個(gè) Uniform 值,即模型視圖矩陣、投影矩陣、視覺(jué)空間中的光源位置、幾何圖形的基本色和將要使用的紋理單元。所需的屬性有 GLT_ATTRIBUTE_VERTEX(頂點(diǎn)分量)、GLT_ATTRIBUTE_NORMAL(表面法線)和 GLT_ATTRIBUTE_TEXTURE0(紋理坐標(biāo))。
二、OpenGL 基礎(chǔ)圖元
OpenGL圖元的模式標(biāo)識(shí)
| 圖元類(lèi)型 | OpenGL 枚舉量 |
|---|---|
| 點(diǎn) | GL_POINTS |
| 線 | GL_LINES |
| 條帶線 | GL_LINE_STRIP |
| 循環(huán)線 | GL_LINE_LOOP |
| 獨(dú)立三角形 | GL_TRIANGLES |
| 三角形條帶 | GL_TRIANGLE_STRIP |
| 三角形扇面 | GL_TRIANGLE_FAN |
1、點(diǎn)和線
(1)點(diǎn)
點(diǎn) 是最簡(jiǎn)單的圖像。每個(gè)特定的頂點(diǎn)在屏幕上都僅僅是一個(gè)單獨(dú)的點(diǎn)。默認(rèn)的情況下,點(diǎn)的大小是一個(gè)像素的大小。我們可通過(guò)調(diào)用glPointSize改變默認(rèn)點(diǎn)的大?。?/p>
void glPointSize(GLfloat size);
// 1.最簡(jiǎn)單也是最常用的 4.0f,表示點(diǎn)的大小
glPointSize(4.0f);
// 2.設(shè)置點(diǎn)的大小范圍和點(diǎn)與點(diǎn)之間的間隔
GLfloat sizes[2] = {2.0f,4.0f};
GLfloat step = 1.0f;
// 獲取點(diǎn)大小范圍和最小步長(zhǎng)(增量)
glGetFloatv(GL_POINT_SIZE_RANGE,sizes);
glGetFloatv(GL_POINT_GRAULARITY,&step);
還可以通過(guò)使用程序點(diǎn)大小模式來(lái)設(shè)置點(diǎn)大小。
// 3.通過(guò)使用程序點(diǎn)大小模式來(lái)設(shè)置點(diǎn)大小
glEnable(GL_PROGRAM_POINT_SIZE);
// 這種模式下允許我們通過(guò)編程在頂點(diǎn)著色器或幾何著色器中設(shè)置點(diǎn)大小。著色器內(nèi)建變量:gl_PointSize,并且可以在著色器源碼直接寫(xiě)
gl_PointSize = 5.0;
(2)線
比點(diǎn)更進(jìn)一步的是獨(dú)立線段。一個(gè)線段就是2個(gè)頂點(diǎn)之間繪制的。
默認(rèn)情況下,線段的寬度是一個(gè)像素。改變線段唯一的方式是使用函數(shù) glLineWidth:
void glLineWidth(GLfloat width);
// 設(shè)置獨(dú)立線段寬度為1.5f;
glLineWidth(1.5f);
(3)線帶
線帶(line strip)連續(xù)地從一個(gè)頂點(diǎn)到下一個(gè)頂點(diǎn)繪制的線段,以形成一個(gè)真正連接點(diǎn)的線條。
(為了把圖形連接起來(lái),每個(gè)連接的頂點(diǎn)會(huì)被選定2次。一次作為線段的終點(diǎn)、一次作為下一條線段的起點(diǎn)),這次是作為GL_LINE_STRIP繪制的。
(4)線環(huán)
線環(huán)(line loop)是線帶的一種簡(jiǎn)單拓展,在線帶的基礎(chǔ)上額外增加了一條連接著一批次中最后一個(gè)點(diǎn)和第一個(gè)點(diǎn)的線段。
2、繪制三角形
可能存在的最簡(jiǎn)單的實(shí)體多邊形就是三角形,它只有3個(gè)邊。光柵化硬件最歡迎三角形。并且現(xiàn)在OpenGL已經(jīng)是OpenGL中支持的唯一一種多邊形。每3個(gè)頂點(diǎn)定義一個(gè)新的三角形。
(1)單獨(dú)的三角形
如下圖是使用 GL_TRIANGLES 繪制的兩個(gè)三角形:

繪制金字塔
下面繪制4個(gè)三角形組成金字塔形的三角形。我們可以使用方向鍵來(lái)旋轉(zhuǎn)金字塔,從不同角度進(jìn)行觀察。但是這個(gè)金字塔木有底面,所以我們可以看到它的內(nèi)部。

代碼如下:
//通過(guò)三角形創(chuàng)建金字塔
GLfloat vPyramid[12][3] = {
-2.0f, 0.0f, -2.0f,
2.0f, 0.0f, -2.0f,
0.0f, 4.0f, 0.0f,
2.0f, 0.0f, -2.0f,
2.0f, 0.0f, 2.0f,
0.0f, 4.0f, 0.0f,
2.0f, 0.0f, 2.0f,
-2.0f, 0.0f, 2.0f,
0.0f, 4.0f, 0.0f,
-2.0f, 0.0f, 2.0f,
-2.0f, 0.0f, -2.0f,
0.0f, 4.0f, 0.0f};
//GL_TRIANGLES 每3個(gè)頂點(diǎn)定義一個(gè)新的三角形
triangleBatch.Begin(GL_TRIANGLES, 12);
triangleBatch.CopyVertexData3f(vPyramid);
triangleBatch.End();
(2)環(huán)繞
將順時(shí)針?lè)较蚶L制的三角形用逆時(shí)針的方式繪制。
如下圖,在繪制第一個(gè)三角形時(shí),線條是按照從V0-V1,再到V2。最后再回到V0的一個(gè)閉合三角形。 這個(gè)是沿著頂點(diǎn)順時(shí)針?lè)较颉?br>
這種順序與方向結(jié)合來(lái)指定頂點(diǎn)的方式稱(chēng)為 環(huán)繞。
下圖的2個(gè)三角形的環(huán)繞方向完全相反。

正面與背面:
在默認(rèn)的情況下,OpenGL認(rèn)為具有逆時(shí)針?lè)较?/strong>環(huán)繞的多邊形是 正面的。而右側(cè)的順時(shí)針?lè)较?/strong>三角形是三角形的 背面。
為什么區(qū)分正背面很重要?
因?yàn)槲覀兂3OM麨橐粋€(gè)多邊形的正面和背面分別設(shè)置不同的物理特征。我們可以完全隱藏一個(gè)多邊形的背面,或者給它設(shè)置一種不同的顏色和反射屬性。紋理圖像在背面三角形中也是相反的。在一個(gè)場(chǎng)景中,使所有的多邊形保持環(huán)繞方向的一致,并使用正面多邊形來(lái)繪制所有實(shí)心物體的表面是非常重要的。
如果想改變OpenGL這個(gè)默認(rèn)行為,可以調(diào)用下面的函數(shù):
glFrontFace(GL_CW);
參數(shù):GL_CW | GL_CCW
GL_CCW:表示傳入的mode會(huì)選擇逆時(shí)針為前向
GL_CW:表示順時(shí)針為前向。
默認(rèn):GL_CCW。逆向時(shí)針為前向。
(3) 三角地帶
對(duì)于很多表面和形狀來(lái)說(shuō),我們可能需要繪制幾個(gè)相連的三角形。我們可以使用GL_TRIANGLE_STRIP圖元繪制一串相連的三角形。從而節(jié)省大量的時(shí)間。

使用三角帶而不是分別指定每個(gè)三角形,這樣做有兩個(gè)優(yōu)點(diǎn):
- 用前3個(gè)頂點(diǎn)指定第1個(gè)三角形之后,對(duì)于接下來(lái)的每一個(gè)三角形,只需要再指定1個(gè)頂點(diǎn)。需要繪制大量的三角形時(shí),采用這種方法可以節(jié)省大量的程序代碼和數(shù)據(jù)存儲(chǔ)空間。
- 提供運(yùn)算性能和節(jié)省帶寬。更少的頂點(diǎn)意味著數(shù)據(jù)從內(nèi)存?zhèn)鬏數(shù)綀D形卡的速度更快,并且頂點(diǎn)著色器需要處理的次數(shù)也更少了。
(4) 三角形扇
除了三角形帶之外,還可以使用GL_TRIANGLE_FAN創(chuàng)建一組圍繞一個(gè)中心點(diǎn)的相連三角形。通過(guò)4個(gè)頂點(diǎn)所產(chǎn)生的包括3個(gè)三角形的三角形扇。 第一個(gè)頂點(diǎn) V0 構(gòu)建了扇形的原點(diǎn),用前3個(gè)頂點(diǎn)指定了最初的三角形之后,后續(xù)的每個(gè)頂點(diǎn)都和原點(diǎn)(V0)以及之前緊挨著它的那個(gè)頂點(diǎn)(Vn-1)形成接下來(lái)的三角形。

3、一個(gè)簡(jiǎn)單批次容器
GLTools 庫(kù)中包含額一個(gè)簡(jiǎn)單的容器類(lèi),叫做 GLBatch。這個(gè)類(lèi)可以作為7種圖元的簡(jiǎn)單批次容器使用。而且它知道在使用GL_ShaderManager支持的任意存儲(chǔ)著色器時(shí)如何對(duì)圖元進(jìn)行渲染。
使用 GLBatch 類(lèi)非常簡(jiǎn)單。首先對(duì)批次進(jìn)行初始化,告訴這個(gè)類(lèi)它代表哪種圖元,其中包括的頂點(diǎn)數(shù),以及(可選)一組或兩組紋理坐標(biāo)。
參數(shù)1:圖元
參數(shù)2:頂點(diǎn)數(shù)
參數(shù)3:一組或者2組紋理坐標(biāo)(可選)
void GLBatch::Begain(GLeunm primitive,GLuint nVerts,GLuint nTexttureUnints = 0);
然后,至少要復(fù)制一個(gè)由3分量(x, y, z)頂點(diǎn)組成的數(shù)組。
//復(fù)制表面法線
void GLBatch::CopyVertexData3f(GLfloat *vVerts);
還可以選擇復(fù)制表面發(fā)現(xiàn)、顏色和紋理坐標(biāo)。
//復(fù)制表面法線
void GLBatch::CopyNormalDataf(GLfloat *vNorms);
//復(fù)制顏色
void GLBatch::CopyColorData4f(GLfloat *vColors);
//復(fù)制紋理坐標(biāo)
void GLBatch::CopyTexCoordData2f(GLFloat *vTextCoords,GLuint uiTextureLayer);
完成上述工作以后,可調(diào)用End來(lái)表明已經(jīng)完成了數(shù)據(jù)復(fù)制工作,并且將設(shè)置內(nèi)部標(biāo)記,以通知這個(gè)類(lèi)包含哪些屬性。
//結(jié)束繪制
void GLBatch::End(void);
實(shí)際上,可以在任何我們想要的時(shí)候進(jìn)行復(fù)制,只要不改變累的大小即可。
而一旦調(diào)用End函數(shù),就不能再增加新的屬性了(也就是說(shuō)我們現(xiàn)在也不能確定是否要有表面法線了)。
關(guān)于提交屬性的 OpengGL 實(shí)際內(nèi)部運(yùn)行機(jī)制實(shí)際上比這要復(fù)雜的多。GLBatch 類(lèi)只是一個(gè)便利類(lèi)(convenience class),就像使用GLUT一樣方便。
以上的總結(jié)參考了并部分摘抄了以下文章,非常感謝以下作者的分享?。?br>
1、《OpenGL超級(jí)寶典 第5版》
2、《OpenGL編程指南(英文第八版)》
3、作者CC老師_HelloCoder的《004--OpenGL 圖元》
轉(zhuǎn)載請(qǐng)備注原文出處,不得用于商業(yè)傳播——凡幾多