一、前言
之前的所有的繪制,不管是三角形還是圖片紋理,我們都使用到了頂點(diǎn)坐標(biāo)數(shù)據(jù),現(xiàn)在這里再說明下,代碼如下:
// 頂點(diǎn)
GLES20.glVertexAttribPointer(mPositionHandle, 3, GLES20.GL_FLOAT, false, 12, mCubeBuffer);
GLES20.glEnableVertexAttribArray(mPositionHandle);
其中g(shù)lVertexAttribPointer是向頂點(diǎn)句柄mPositionHandle中賦值。glEnableVertexAttribArray是啟動(dòng)頂點(diǎn)數(shù)組。
glVertexAttribPointer的過程是每次從內(nèi)存中傳入到GPU中,而對(duì)于頂點(diǎn)來說,該頂點(diǎn)坐標(biāo)是很少改變的,不需要每次使用的時(shí)候都要重新傳遞,這會(huì)浪費(fèi)帶寬。由此引出了VBO(頂點(diǎn)緩沖對(duì)象),讓頂點(diǎn)的數(shù)據(jù)直接在GPU緩沖區(qū)中,每次使用的時(shí)候就直接從緩沖區(qū)中取出,而減少數(shù)據(jù)的傳輸和帶寬的使用。
二、VBO使用
- 1、創(chuàng)建VBO
int[] vbos = new int[1];
GLES20.glGenBuffers(vbos.length, vbos, 0);
vboId = vbos[0];`
生成VBO,采用glGenBuffers,這里面可以控制生成的緩沖區(qū)個(gè)數(shù),這里面就生成一個(gè)即可。
- 2、綁定VBO
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
注意:VBO的類型是GL_ARRAY_BUFFER,所以需要綁定的類型是GL_ARRAY_BUFFER,對(duì)應(yīng)的VBO的句柄是vboId
- 3、賦值
我們現(xiàn)在創(chuàng)建了一個(gè)名叫"vboId" 的VBO緩沖了,接下來就需要向這個(gè)緩沖區(qū)中存入數(shù)據(jù)了。只有綁定了緩沖區(qū)后才可以存入數(shù)據(jù)。
GLES20.glBufferData(GLES20.GL_ARRAY_BUFFER,triangleCoords.length * 4,vertexBuffer,GLES20.GL_STATIC_DRAW);
GLES20.GL_ARRAY_BUFFER : VBO的類型
triangleCoords.length * 4 : 存入的數(shù)據(jù)大小,4是float大小
vertexBuffer : 數(shù)據(jù)源,ByteBuffer
GLES20.GL_STATIC_DRAW : 代表數(shù)據(jù)源不會(huì)變化
- 4、解綁
在不使用VBO的時(shí)候,需要對(duì)該VBO進(jìn)行解綁。解綁就是讓GL_ARRAY_BUFFER綁定0
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
- 5、使用
之前使用的是glVertexAttribPointer,并傳入一個(gè)數(shù)據(jù)源。使用了VBO后,我們使用的是glVertexAttribPointer的另一個(gè)重載方法。
由于上一次已經(jīng)對(duì)VBO解綁了,那么我們使用的時(shí)候需要重新的進(jìn)行綁定操作。這樣我們在傳值的時(shí)候,就知道了我們使用的是哪個(gè)VBO了。
對(duì)于glVertexAttribPointer操作,我們從只要告訴取值的大小,偏移量等必要條件后就可以從緩沖區(qū)中取出對(duì)應(yīng)的數(shù)據(jù)了。
使用完成后,依然需要對(duì)VBO解綁。
//準(zhǔn)備三角形的坐標(biāo)數(shù)據(jù)
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, vboId);
GLES20.glVertexAttribPointer(mPositionHandle, 3,
GLES20.GL_FLOAT, false,
12,0);
GLES20.glBindBuffer(GLES20.GL_ARRAY_BUFFER, 0);
三、代碼
代碼整合在github