opengl es3.0學習篇四:頂點屬性,頂點數組和緩衝區對象

資料來源:html

OpenGL ES3.0編程指南java

https://www.cnblogs.com/gaofengworking/p/4943204.htmlc++

https://blog.csdn.net/tianxiawuzhei/article/details/46639553編程

頂點數據也稱做頂點屬性,指定每一個頂點的數據。這種逐頂點數據能夠爲每一個頂點指定,也能夠用於全部的頂點的常量。數組

想要繪製一個固定顏色的三角形,能夠指定一個常量用於三角形的所有三個頂點緩存

常量頂點屬性

常量頂點屬性對於一個圖元的全部頂點都相同,因此對一個圖元的全部頂點只須要採用一個值:ide

void glVertexAttrib1f(GLuint index, GLfloat x);
void glVertexAttrib2f(GLuint index, GLfloat x, GLfloat y);
void glVertexAttrib3f(GLuint index, GLfloat x, GLfloat y, GLfloat z);
void glVertexAttrib4f(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);

void glVertexAttrib1fv(GLuint index, const GLfloat * values);
void glVertexAttrib2fv(GLuint index, const GLfloat * values);
void glVertexAttrib3fv(GLuint index, const GLfloat * values);
void glVertexAttrib4fv(GLuint index, const GLfloat * values);

上面這些命令用來給由index指定的頂點屬性加載數據。其中glVertexAttrib1fglVertexAttrib1fv會加載(x, 0.0, 0.0, 1.0),glVertexAttrib2fglVertexAttrib2fv會加載(x, y, 0.0, 1.0),glVertexAttrib3fglVertexAttrib3fv會加載(x, y, z, 1.0),glVertexAttrib4fglVertexAttrib4fv會加載(x, y, z, w)。在實際中,常量頂點屬性提供了和使用標量/向量統一變量等價的功能,二者均可以選用。性能

頂點數組

頂點數組指定每一個頂點的屬性,是保存在應用程序地址空間的緩衝區。頂點數組用glVertexAttribPointer()或者glVertexAttribIPointer()來指定:ui

GLES30.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                GLES30.GL_FLOAT, false,
                vertexStride, vertexBuffer);
//參數一:通用屬性的句柄,在上個demo中指的是mPositionHandle
//參數二,指的是一個頂點的屬性包含的size的值,在demo中設置爲3
//參數三:數據格式,與數組的type一致
//參數四:標識非浮點數據在轉換成浮點時是否規範化
//參數五:每一個頂點由size指定的定點屬性份量的順序存儲,即告訴程序對應每一個頂點的位置
//參數六:頂點數組

頂點緩衝區對象(VBOS)

當使用頂點數組的時候,頂點數據是保存在客戶內存中(通常指cpu),在進行glDrawArray()或者glDrawElements()等繪圖調用時候,這些數據會從客戶內存複製到圖形內存(指gpu)。**若是咱們沒有必要再繪圖調用時都複製頂點數據,則能夠在圖形內存中緩存這些數據,這種方法能夠改善渲染性能,也會下降內存和電力的消耗。**這就是頂緩衝區對象的意義。.net

頂點緩衝區對象讓opengl es應用程序在圖像內存中分配和緩存數據,而且在這個內存中渲染,避免每次繪製圖元時候從新發送數據

3.0中支持兩類緩衝區對象,用於指定頂點和圖元數據:

  • **數組緩衝區對象。**標識GL_ARRAY_BUFFER指定數組緩衝區對象用於建立保存頂點數據的緩衝區對象
  • **元素數組緩衝區對象。**GL_ELEMENT_ARRAY_BUFFER標識指定的元素數組緩衝區對象用於建立保存圖元索引的緩衝區對象。

數組緩衝區用於保存一個或者多個圖元的頂點屬性數據,而元素數組緩衝區對象保存了一個或者多個圖元的索引,以數組緩衝區作例子:

private void createVertextBuffer(){
        int[] value = new int[1];
        GLES30.glGenBuffers(1, value,0);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, value[0]);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER,vertexBuffer.position(),vertexBuffer,GLES30.GL_STATIC_DRAW);
    }
  • glGenBuffers()用來獲取未使用的緩衝對象,其中參數一標識須要返回的緩衝對象數量,參數二標識返回分配的緩衝對象的位置句柄。

注意:glGenBuffers()返回的句柄是0之外的無符號整數,0值由opengl es保留

  • glBindBuffer()用於指定當前緩衝區對象,參數一使用GL_ARRAY_BUFFER或者GL_ELEMENT_ARRAY_BUFFER來標識緩衝對象,參數二表示須要使用的緩衝區對象句柄。
  • glBufferData()用來綁定緩衝區數據,參數一與上相同,參數二標識緩衝區的數據存儲大小(以字節數表示),,參數三爲數據,參數四爲使用緩衝區存儲的數據對象的提示。若是參數三是一個有效數據,則內容會被複制且分配到緩衝區對象中。

在Android中的使用(居於http://www.javashuo.com/article/p-rapaesnz-kq.html Demo改進):

private void createVertextBuffer(){
        int[] value = new int[1];
        GLES30.glGenBuffers(1, value,0);
        GLES30.glBindBuffer(GLES30.GL_ARRAY_BUFFER, value[0]);
        GLES30.glBufferData(GLES30.GL_ARRAY_BUFFER,vertexBuffer.capacity()*4,vertexBuffer,GLES30.GL_STATIC_DRAW);
    }

public void onDraw(){
        // Add program to OpenGL ES environment
        GLES30.glUseProgram(mProgram);

        // get handle to vertex shader's vPosition member
        mPositionHandle = GLES30.glGetAttribLocation(mProgram, "vPosition");
        createVertextBuffer();
        // Enable a handle to the triangle vertices
        GLES30.glEnableVertexAttribArray(mPositionHandle);
        // Prepare the triangle coordinate data
        GLES30.glVertexAttribPointer(mPositionHandle, COORDS_PER_VERTEX,
                GLES30.GL_FLOAT, false,
                0, 0);//這裏注意最後兩個參數須要改爲0,0標明不從cpu中拿數據了,從gpu拿數據,因此方法是不同的
        // get handle to fragment shader's vColor member
        mColorHandle = GLES30.glGetAttribLocation(mProgram, "aColor");

        // Set color for drawing the triangle
        GLES30.glVertexAttrib4fv(mColorHandle,  color, 0);

        // Draw the triangle
        GLES30.glDrawArrays(GLES30.GL_TRIANGLES, 0, vertexCount);

        // Disable vertex array
        GLES30.glDisableVertexAttribArray(mPositionHandle);
    }

總而言之,使用頂點緩衝區對象可以減小cpu和gpu之間複製的數據量,從而得到更好的性能。

頂點數組對象(VAO)

這個特性是在opengl es3.0 中引入的,提供包含在頂點數組/頂點緩衝區對象配置之間切換所須要的全部狀態的單一對象.只須要在設置緩衝區數據的時候glGenVertexArrays一個頂點數組對象ID,而後調用glBindVertexArray綁定已經生成數組對象的ID,在繪製圖元的時候調用glBindVertexArray切換相應緩衝區內的數據並進行繪製.glDeleteVertexArray刪除一個或者多個頂點數組對象.

映射緩衝區對象

應用程序設置緩衝區對象數據調用glBufferData的時候,能夠將緩衝區對象數據存儲映射到應用程序的內存地址空間,優勢:減小應用程序的內存佔用,只須要存儲數據的一個副本.避免數據複製步驟經過映射出的GPU存儲緩衝區對象的內存地址. 調用glMapBufferRange返回緩衝區存儲數據範圍的指針,出現錯誤則反悔NULL,glUnmapBuffer取消以前緩衝區映射。

相關文章
相關標籤/搜索