一個屬性能夠聲明在一個頂點着色器,但若是它不使用,那麼它是不被激活的。你能使用glGetActiveAttrib查詢一個被激活的屬性內容。GL_ACTIVE_ATTRIBUTESgit
void glGetActiveAttrib( GLuint program, GLuint index, GLsizei bufsize, GLsizei *length, GLint *size, GLenum *type, GLchar *name)
bufsize是那些能被寫爲屬性名的字符的最大數目,包括空('\0')。length是返回的名字長度,type是數據的類型GL_FLOAT等。size是返回的屬性大小,是返回type的單位大小,若是是數組就是數組的尺寸,不是數組就是1。name是着色器聲明的屬性變量的名字。github
頂點着色器中使用glBindAttribLocation綁定一個普通的頂點屬性索引到屬性變量,這個綁定在項目下次連接時有效,在當前連接的項目裏不會改變。若是一個名字前面被綁定過,它分配的綁定被一個索引取代。glBindAttribLocation甚至能在頂點着色器被鏈接到一個項目對象前使用。這意味着這個調用能被使用去綁定任何屬性名字。屬性名字不存在或者沒激活的綁定在項目裏被忽略。segmentfault
void glBindAttribLocation(GLuint program, GLuint index, const GLchar *name)
另外一種選擇是讓GLES綁定屬性變量名到一個普通的屬性索引。在連接階段GLES2爲每一個屬性變量執行下面的步驟:檢查每一個屬性變量是否已經過glBindAttribLocation綁定。若是已綁定,指定的屬性索引將被使用;若是沒有,編譯工具將產生一個通常的頂點屬性索引。而這個分配依賴工具的不一樣而不一樣,咱們可使用glGetAttribLocation去獲取這個分配的值。api
GLint glGetAttribLocation(GLuint program, const GLchar *name)
指定頂點屬性常量數組
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是要裝載的頂點屬性索引,x y z values是要填充的值。glVertexAttrib?f和glVertexAttrib?fv都是裝載一個vec4的值。介紹Shader語言時說過它們都會存儲爲具備4個份量的存儲單元。填充時最後一個會爲1.0,中間不足的爲0.0。如glVertexAttrib1fv填充1,那麼index最終的值爲{x,0.0,0.0,1.0}。注意到GLES2只支持了浮點型的設置屬性常量api。less
頂點數組ide
void glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride, const void *ptr)
要裝在數組到頂點屬性,使用glVertexAttribPointer,index是頂點屬性的索引,size是數組裏組成元素的大小(例如只是指定二維的位置那麼只須要x,y那麼賦值爲2),type是數據格式,normalized用於指定非浮點數據格式轉變成浮點型數據時是否標準化,strides是頂點屬性數據的存儲間隔,0表示無間隔,連續存儲的。ptr就是咱們要放進去的數據了。正如第二節例子裏的:工具
// _vPositionHandle的值就來自於glGetAttribLocation獲取獲得的索引 glVertexAttribPointer(_vPositionHandle, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices);
出了加載數據,咱們還要爲屬性啓用屬性數組。oop
// 啓用 void glEnableVertexAttribArray(GLuint index); // 不啓用 void glDisableVertexAttribArray(GLuint index); // index就是前面的屬性索引值
接着之前的項目,這裏咱們主要修改Director裏的內容:代碼看裏面的lesson5的tagui
想聲明着色器和全局數據
// 頂點着色器,聲明倆個着色器屬性,分別放位置和顏色,易變變量做爲輸出將傳給片斷着色器 static const char gVertexShader[] = "attribute vec4 a_position;\n" "attribute vec4 a_color;\n" "varying vec4 v_color;\n" "void main()\n" "{\n" " v_color = a_color;\n" " gl_Position = a_position;\n" "}\n"; // 片斷着色器,接收顏v_color傳來的顏色 static const char gFragmentShader[] = "varying vec4 v_color;\n" "void main()\n" "{\n" " gl_FragColor = v_color;\n" "}\n"; // 和之前的同樣的三角形數據 const GLfloat gTriangleVertices[] = { 0.0f, 0.5f, -0.5f, -0.5f, 0.5f, -0.5f }; // 接下來用給a_color的 const GLfloat gColor[4] = { 1.0f, 1.0f, 0.0f, 1.0f };
在mainloop循環中修改
void Director::mainLoop() { static float grey; grey += 0.01f; if (grey > 1.0f) { grey = 0.0f; } glClearColor(grey, grey, grey, 1.0f); glClear( GL_DEPTH_BUFFER_BIT | GL_COLOR_BUFFER_BIT); glVertexAttrib4fv(0, gColor); glVertexAttribPointer(1, 2, GL_FLOAT, GL_FALSE, 0, gTriangleVertices); glEnableVertexAttribArray(1); glBindAttribLocation(_glProgram->getProgramHandle(), 0, "a_color"); glBindAttribLocation(_glProgram->getProgramHandle(), 1, "a_position"); glDrawArrays(GL_TRIANGLES, 0, 3); }
查看效果,能夠看到咱們設置的黃色三角形: