1. 程式人生 > >從零開始Java遊戲引擎[LWJGL](4)-使用索引快取

從零開始Java遊戲引擎[LWJGL](4)-使用索引快取

如果只是有頂點緩衝的話(即使有glDrawArray進行繪製),會儲存頂點冗餘。例如:顯示一個矩形,要畫2個三角形,每個三角形3個頂點,就要準備6個頂點傳遞到glDrawArray函式中。其實,畫一個矩形只需要4個頂點就可以了,不是嗎?

你可能認為,這有什麼的?不就是多傳遞了2個頂點嗎?其實不然,你現在只是畫2個三角形,當你畫一個吃雞的場景時,裡面的人物,地形,建築,槍械等等,所有的物體都需要使用三角形進行繪製,如果儲存頂點冗餘的話,則會降低幀率。

為什麼會降低幀率?因為在渲染的時候,頂點資料是從CPU傳送到GPU進行頂點計算的,GPU的記憶體(視訊記憶體)是十分寶貴的,想想現在的顯示卡賣多貴。所以,我們要利用有限的視訊記憶體,繪製儘可能多的物體,且在執行的幀率範圍內。

說了這麼多,就是讓你不要再使用glDrawArray了。當然,如果你畫GUI的話,那無所謂。反正也沒多少個點嘛。

ok。開始程式碼了。

修改Loader.java的程式碼,繫結索引快取。


// 增加 int[] indices
public RawModel loadToVAO(float[] positions, int[] indices){    
    int vaoID = createVAO();
    bindIndicesBuffer(indices);
    //配置vao
    storeDataInAttributesList(0, 3,positions);
    unbindVAO();
    return
new RawModel(vaoID, indices.length); } // 增加繫結索引快取函式 private void bindIndicesBuffer(int[] indices){ int vboID = GL15.glGenBuffers(); vbos.add(vboID); GL15.glBindBuffer(GL15.GL_ELEMENT_ARRAY_BUFFER, vboID); IntBuffer buffer = storeDataInIntBuffer(indices); GL15.glBufferData(GL15.GL_ELEMENT_ARRAY_BUFFER, buffer, GL15.GL_STATIC_DRAW); }
// 替換Renderer.java中的render函式中的glDrawArray函式
    //GL11.glDrawArrays(GL11.GL_TRIANGLES, 0, model.getVertexCount());
    GL11.glDrawElements(GL11.GL_TRIANGLES, model.getVertexCount(),GL11.GL_UNSIGNED_INT,0);
// 測試

// 現在我們只需要4個頂點就夠了
float[] positions = {
        -0.5f,0.5f,0.0f,
        -0.5f,-0.5f,0.0f,
        0.5f,-0.5f,0.0f,
        0.5f,0.5f,0.0f
        };

int []indices = {
        0,1,3,
        3,1,2


RawModel model =  loader.loadToVAO(positions,indices);

執行效果和之前的一樣。

ok。結束。

下篇預告:使用Shader。

原始碼下載