1. 位圖
像素?cái)?shù)據(jù)由位圖(一系列表示像素值開(kāi)啟和關(guān)閉0,1)來(lái)表示的。每個(gè)內(nèi)存中存儲(chǔ)的位圖數(shù)據(jù)和像素開(kāi)啟和關(guān)閉是一一對(duì)應(yīng)的。
2. 像素包裝
像素?cái)?shù)據(jù)的字節(jié)以特定方式與地址對(duì)齊的方式。比如說(shuō)很多計(jì)算機(jī)CPU每四個(gè)字節(jié)從緩沖區(qū)讀取數(shù)據(jù),而以每四個(gè)字節(jié)與地址對(duì)齊的方式,可以提高其讀寫(xiě)效率。
3. 像素圖
像素圖屬于位圖,像素圖的位數(shù)比較多,一般為8位,16位和32位,可以顯示的顏色為2的位數(shù)次方,此外像素圖還有一個(gè)附加位,用來(lái)表示屏幕的兩度或者顏色值的強(qiáng)度。OpenGL中無(wú)法將像素?cái)?shù)據(jù)寫(xiě)入到顏色緩沖區(qū),但是可以指定顏色緩沖區(qū)內(nèi)容,也就是我們用一種形式表示圖像數(shù)據(jù),通過(guò)直接讀取顏色緩沖區(qū)的數(shù)據(jù)而間接的提取出相關(guān)的像素?cái)?shù)據(jù)。比如說(shuō)可以通過(guò)這個(gè)函數(shù)進(jìn)行提取。
void glReadPixels(GLint x, GLint y, GLsizei width, GLsizei height, GLenum format, GLenum type, const void *pixels);
x, y為矩形窗口在窗口左下角坐標(biāo),width和height為矩形寬和高,矩形為對(duì)應(yīng)圖像數(shù)據(jù)的區(qū)域。pixels指針為圖像數(shù)據(jù)在內(nèi)存中的地址。format為pixels指向的顏色緩沖區(qū)存取數(shù)據(jù)元素的顏色布局。type為pixels指向顏色緩沖區(qū)存取的數(shù)據(jù)類型。
需要注意的,glReadPixelds從圖形硬件中復(fù)制數(shù)據(jù),通常通過(guò)總線傳輸?shù)絻?nèi)存,這種情況下應(yīng)用程序會(huì)被阻塞,直到內(nèi)存?zhèn)鬏斖瓿?而且指定一個(gè)與本地圖形硬件不同的像素布局,也會(huì)帶來(lái)額外的開(kāi)銷.
4. 包裝的像素格式
如果一個(gè)字節(jié)等于8位,通常我們用八位表示三原色的一個(gè)分量,那么顯示一種顏色需要三個(gè)字節(jié),但是經(jīng)過(guò)包裝后,比如說(shuō)我們可以用八位就可以表示一種顏色,比如說(shuō)從高位到低位,沒(méi)三位表示三原色的一種分量,后一位表示一種三原色的分量,這樣對(duì)圖像數(shù)據(jù)進(jìn)行包裝,可以節(jié)省大量的內(nèi)存的空間.或者更快的進(jìn)行操作.
5. 載入紋理
將紋理數(shù)據(jù)載入到內(nèi)存中,在OpenGL一般我們通過(guò)下面三個(gè)函數(shù)
void glTexImage1d(GLenum target, GLint level, GLint internalformat , GLseizei width, GLint border , GLenum format, GLenum type, void *data)
void glTexImage2d(GLenum target, GLint level, GLint internalformat , GLseizei width, GLseizei height, GLint border , GLenum format, GLenum type, void *data)
void glTexImage3d(GLenum target, GLint level, GLint internalformat , GLseizei width, GLseizei height, GLseizei depth, GLint border , GLenum format, GLenum type, void *data)
target參數(shù)為載入紋理單元的模式,level為mip的層次,internalformat為每個(gè)紋理單元存儲(chǔ)的顏色成分,如果指定顏色組成的特定方式,也可作為壓縮紋理數(shù)據(jù)的參數(shù),width,height,depth指定了被加載紋理數(shù)據(jù)的范圍, border為每個(gè)紋理單元額外的邊界。format為紋理數(shù)據(jù)的顏色布局,type為存儲(chǔ)到內(nèi)存中的紋理數(shù)據(jù)類型,data為紋理數(shù)據(jù)對(duì)應(yīng)的地址指針。
6.從顏色顏色緩存區(qū)讀取紋理數(shù)據(jù)
可以使用下面兩個(gè)函數(shù)
void glCopyTexImage1d(GLenum target, GLint level, GLint internalformat , GLint x, GLseizei width, GLint border)
void glCopyTexImage2d(GLenum target, GLint level, GLint internalformat , GLint x, GLint y, GLseizei width, GLseizei height, GLint border)
其中x,y為指定內(nèi)存中要加載紋理的位置,需要注意的是顏色緩沖區(qū)沒(méi)有深度的概念,故不能加載三維的紋理數(shù)據(jù)。
7. 更新紋理
頻繁的載入紋理數(shù)據(jù),實(shí)際上是對(duì)內(nèi)存的寫(xiě)操作,內(nèi)存的寫(xiě)操作是很耗性能的,當(dāng)我們不在需要這段紋理時(shí),這時(shí)候我們可以在這段紋理的內(nèi)存上進(jìn)行紋理的替換或者部分替換,而避免再次重新寫(xiě)入新的紋理數(shù)據(jù)。下面幾個(gè)函數(shù)可以完成紋理更新
void glTexSubImage1d(GLenum target, GLint level, GLint xOffset, GLseizei width, GLint border , GLenum format, GLenum type, void *data )
void glTexSubImage2d(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLseizei width, GLseizei height, GLint border , GLenum format, GLenum type, void *data)
oid glTexSubImage3d(GLenum target, GLint level , GLint xOffset, GLint yOffset, GLint zOffset, GLseizei width, GLseizei height, GLint border , GLenum format, GLenum type, void *data)
其中xOffset,yOffset,zOffset,為需要更新的紋理在原紋理的坐標(biāo)偏移量。
8.在顏色顏色緩存區(qū)更新紋理
void glCopyTexSubImage1d(GLenum target, GLint level, GLint xOffset, GLint x, GLint y, GLseizei width )
void glCopyTexSubImage2d(GLenum target, GLint level, GLint xOffset, GLint yOffset, GLint x, GLint y, GLseizei width, GLseizei height)
oid glCopyTexSubImage3d(GLenum target, GLint level , GLint xOffset, GLint yOffset, GLint zOffset, GLint x, GLint y, GLseizei width, GLseizei height)
需要注意的地方從顏色緩存區(qū)讀取紋理數(shù)據(jù)是沒(méi)有g(shù)lCopyTexImage3d函數(shù)的,這是因?yàn)轭伾彌_區(qū)是沒(méi)有深度概念的,只可以將2D彩色圖片設(shè)置成2D紋理,但是我們更新顏色緩沖區(qū)的紋理是可以使用glCopyTexSubImage3d函數(shù)的,因?yàn)榧y理有深度的概念,我們可以用紋理單元平面來(lái)設(shè)置一個(gè)二維的紋理。
9.紋理對(duì)象
當(dāng)載入紋理數(shù)據(jù)后,這時(shí)候我們是需要管理這些紋理的,如果用到哪個(gè)紋理狀態(tài)就加載哪個(gè)紋理數(shù)據(jù)或者更新哪個(gè)紋理的話,這樣顯然是很耗費(fèi)性能的,紋理對(duì)象允許一次加載多個(gè)紋理,通過(guò)一段特定的無(wú)符號(hào)整形數(shù)據(jù)一個(gè)指針指向這段紋理內(nèi)存,這樣我們通過(guò)紋理對(duì)象可以方便的進(jìn)行多個(gè)紋理的管理。
首先使用下面這個(gè)函數(shù)進(jìn)行紋理對(duì)象的分配
void glGenTextures(GLSizei n, GLint * textures)
n為紋理對(duì)象的個(gè)數(shù), textures為紋理對(duì)象集合的指針
通過(guò)下面的函數(shù)進(jìn)行紋理與紋理對(duì)象的綁定
void glBindTexture(GLEnum target, GLint *texture)
target為紋理數(shù)據(jù)的坐標(biāo)形式,teture為指向紋理內(nèi)存的指針。
可以使用下面的函數(shù)進(jìn)行紋理對(duì)象的刪除
void glDeleteTextures(GLSizei n, GLint * textures)
n為要?jiǎng)h除的紋理個(gè)數(shù),textures為要?jiǎng)h除的紋理集合
可以使用下面的函數(shù)判斷紋理對(duì)象是否有綁定紋理狀態(tài)
GLboolean GLIsTexture(GLint teure)
teure為要判讀是否存在的紋理對(duì)象