opengles 顶点数组 android,OpenGLES顶点属性、顶点数组和缓冲区对象
頂點屬性數據可以用一個頂點數組對每個頂點指定,也可以將一個常量值用于一個圖元的所有頂點
OpenGLES支持最少16個頂點屬性。準確查詢頂點數量方法如下:
GLint maxVertexAttribs;
glGetIntegerv(GL_MAX_VERTEX_ATTRIBS, &maxVertexAttribs);
一、指定頂點數組
1、常量頂點屬性:
常量頂點屬性對于一個圖元的所有頂點都相同,所以對一個圖元的所有頂點只需指定一個值。函數如下:
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, GLfloat x);
void glVertexAttrib2fv(GLuint index, GLfloat x, GLfloat y);
void glVertexAttrib3fv(GLuint index, GLfloat x, GLfloat y, GLfloat z);
void glVertexAttrib4fv(GLuint index, GLfloat x, GLfloat y, GLfloat z, GLfloat w);
glVertexAttrib* 命令用于加載index 指定的通用頂點屬性。
2、頂點數組
頂點數組指定每個頂點的屬性,是保存應用程序地址空間的緩沖區。他們作為頂點緩沖對象的基礎,提供指定頂點屬性數據的一個高效、靈活的手段。
void glVertexAttribPointer(GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr);
void glVertexAttribIPointer(GLuint index, GLint size, GLenum type, GLsizei stride, const void *ptr);
index - 指定通用頂點屬性索引。
size - 頂點數組中為索引引用的頂點屬性所指定的分量數量。
type - 數據格式,兩條函數均有的值:GL_BYTE,GL_UNSIGNED_BYTE,GL_SHORT,GL_UNSIGNED_SHORT,GL_INT,GL_UNSIGNED_INT,glVertexAttribPointer還包括GL_HALF_FLOAT,GL_FLOAT,GL_FIXED,GL_INT_2_10_10_10_REV,GL_UNSIGNED_INT_2_10_10_10_REV
normalized - 用于表示非浮點數據格式類型在轉換為浮點值時是否應該規范化。對于glVertexAttribIPointer來說,這些值被當作整數對待
stride - 每個頂點由size指定頂點屬性分量順序存儲。stride指定頂點索引 表示頂點數據之間的位移,大于0,表示使用該值作為下一個索引表示的頂點數據的跨距。
ptr - 如果使用客戶端頂點數據,則保存頂點屬性數據的緩沖區的指針,如果使用頂點緩沖區對象,則表示該緩沖區內的偏移量。
分配和存儲頂點屬性數據有兩種常用的方法:
在一個緩沖區中存儲頂點屬性 —— 這種方法稱為結構數組。結構表示頂點的所有屬性,每個頂點有一個屬性的數組。結構數組的分配方法通常是最高效的。
在單獨的緩沖區中保存每個頂點屬性 —— 這個方法稱為數組結構。
頂點屬性使用哪種數據格式
glVertexAttribPointer 中用type參數指定的頂點屬性數據格式不僅影響頂點屬性數據的圖形內存存儲需求,而且影響整體性能。OpenGLES 3.0開始支持GL_HALF_FLOAT 的16位浮點頂點格式,建議盡可能使用GL_HALF_FLOAT,即紋理、坐標、法線、副法線、切向量等使用GL_HALF_FLOAT,顏色存儲為GL_UNSIGNED_BYTE,每個頂點顏色具有4個分量。
glVertexAttribPointer中規范化標志是如何工作的?
在用于頂點著色器之前,頂點屬性在內部保存為單精度浮點數。如果數據類型表示頂點屬性不是浮點數,頂點屬性將在用于頂點著色器之前轉換為單精度浮點數。規范化標志控制非浮點數頂點屬性數據到單精度浮點值的轉換,標志為假時,頂點數據被肢解轉換為浮點數,如果為真且數據類型為GL_BYTE、GL_SHORT、GL_FIXED,則頂點數據被映射到[-1.0, 1.0]范圍內,如果數據類型為GL_UNSIGNED_BYTE或GL_UNSIGNED_SHORT,則被映射到[0.0, 1.0]范圍內。如果想要按照整數的形式訪問整數型頂點,應該使用glVertexAttribIPointer。
常量頂點屬性和頂點數組之間選擇
glEnableVertexAttribArray 和 glDisableVertexAttribArray 命令分別用于啟用和禁用通用頂點屬性數組。
二、在頂點著色器中聲明頂點屬性變量
屬性變量也可以選擇包含一個布局限定符,提供屬性索引。示例:
layout(location = 0) in vec4 a_postion;
layout(location = 1) in vec2 a_texcoord;
layout(location = 2) in vec3 a_normal;
頂點著色器中聲明為頂點屬性的變量是只讀變量,不能修改。屬性可以在頂點著色器內部聲明,不使用不會被認為是活動屬性,著色器屬性數量不能大于GL_MAX_VERTEX_ATTRIBS,否則無法被鏈接。
將頂點屬性綁定到頂點著色器中的屬性變量
頂點屬性由in限定符指定,活動屬性數量可以用glGetProgramiv查詢,程序中活動屬性列表可以用glGetActiveAttrib查詢。
指定通用頂點屬性和綁定到頂點著色器中的屬性名稱:
OpenGLES3.0中,可以使用3種方法將通用頂點屬性索引映射到頂點著色器中的一個屬性變量名稱。
1、索引在源碼中用layout(location = N)聲明指定
2、OpenGLES3.0將通用頂點屬性索引綁定到屬性名稱
3、應用程序可以將頂點屬性索引綁定到屬性名稱
使用glBindAttribLocation命令可以將通用頂點屬性索引綁定到頂點著色器中的一個屬性變量。這種綁定在下一個程序鏈接時生效——不會改變當前鏈接的程序中使用的綁定。
另外,也可以使用glGetAttribLocation命令查詢分配的綁定,需要在返回program定義的程序獨享最后一次鏈接時綁定到屬性變量的通用屬性索引。
三、頂點緩沖區對象
頂點數組指定的頂點數據保存在客戶內存中。在進行glDrawArrays活著glDrawElements等繪圖調用時,這些數據必須同客戶內存復制到圖形內存。
沒必要每次繪圖時都復制頂點數據,而是在圖形內存中緩存這些數據,這樣可以顯著改善渲染性能,也可以降低內存帶寬和電力消耗需求。這就是頂點緩沖區對象發揮作用的地方。
不緊緊是頂點數據,描述圖元頂點索引、作為glDrawElements參數傳遞的元素索引也可以緩存。
GL_ARRAY_BUFFER 指定的數組緩沖區對象用于創建保存頂點數據的緩沖區對象。
GL_ELEMENT_ARRAY_BUFFER 指定的元素數組緩沖區對象用于保存圖元索引的緩沖區對象。
創建和綁定頂點緩沖區對象例子:
void initVertexBufferObjects(vertex_t *vertexBuffer,
GLushort *indices,
GLuint numVertices,
GLuint numIndices,
GLuint *vboIds) {
// 獲取vboIds中兩個未用的緩沖區對象名稱。然后vboIds返回的未使用的緩沖區對象名稱用于創建一個數組緩沖區對象
// 和一個元素數組緩沖區對象。數組緩沖區對象用于保存一個或多個圖元的頂點屬性數據。
glGenBuffers(2, vboIds);
glBindBuffer(GL_ARRAY_BUFFER, vboIds[0]);
glBufferData(GL_ARRAY_BUFFER, numVertices *sizeof(vertex_t),
vertexBuffer, GL_STATIC_DRAW);
glBindBuffer(GL_ELEMENT_ARRAY_BUFFER, vboIds[1]);
glBufferData(GL_ELEMENT_ARRAY_BUFFER, numIndices *sizeof(GLushort),
indices, GL_STATIC_DRAW);
}
glGenBuffers(GLsizei n, GLuint * buffers) :分配n個緩沖區對象名稱,并在buffers中返回它們。
glBindBuffer 用于指定當前緩沖區對象。第一次通過調用glBindBuffer綁定緩沖區對象名稱時,緩沖區對象可以默認狀態分配;如果分配成功,則分配的對象綁定微目標的當前緩沖區對象。
glBufferData 用于創建和初始化頂點數組或元素數組
總結
以上是生活随笔為你收集整理的opengles 顶点数组 android,OpenGLES顶点属性、顶点数组和缓冲区对象的全部內容,希望文章能夠幫你解決所遇到的問題。
- 上一篇: SFTP和FTS协议的区别
- 下一篇: Ubuntu: 软件库(software