mGlProgram = createProgram(mVertexScript, mFragmentScript); glUseProgram(mGlProgram); //reject attribution GLuint a_pos = glGetAttribLocation(mGlProgram, "a_pos"); GLuint a_tex_coord = glGetAttribLocation(mGlProgram, "a_tex_coord"); //active attribution glEnableVertexAttribArray(a_pos); glEnableVertexAttribArray(a_tex_coord); //assigne attribution glVertexAttribPointer(a_pos, 3, GL_FLOAT, GL_TRUE, sizeof(vertex), 0); glVertexAttribPointer(a_tex_coord, 2, GL_FLOAT, GL_TRUE, sizeof(vertex), (GLvoid*) (sizeof(float) * 3)); //glEnable(GL_TEXTURE_2D); glPixelStorei(GL_PACK_ALIGNMENT, 1); // set 4 bytes for the buffer. glPixelStorei(GL_UNPACK_ALIGNMENT, 1); glActiveTexture(GL_TEXTURE0); glGenTextures(1, &mY); glBindTexture(GL_TEXTURE_2D, mY); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE);//if widht and height not 2^n , should set this glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width, height, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); glGenTextures(1, &mU); glBindTexture(GL_TEXTURE_2D, mU); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width >> 1, height >> 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); glGenTextures(1, &mV); glBindTexture(GL_TEXTURE_2D, mV); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MAG_FILTER, GL_LINEAR); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, GL_CLAMP_TO_EDGE); glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, GL_CLAMP_TO_EDGE); glTexImage2D(GL_TEXTURE_2D, 0, GL_LUMINANCE, width >> 1, height >> 1, 0, GL_LUMINANCE, GL_UNSIGNED_BYTE, NULL); glDrawElements(GL_TRIANGLES, num, GL_UNSIGNED_BYTE, 0); glFlush();
Function:數組
void glVertexAttribPointer( GLuint index, GLint size, GLenum type, GLboolean normalized, GLsizei stride,const GLvoid * pointer); 參數: index 指定要修改的頂點屬性的索引值 size 指定每一個頂點屬性的組件數量。必須爲一、二、3或者4。初始值爲4。(如position是由3個(x,y,z)組成,而顏色是4個(r,g,b,a)) type 指定數組中每一個組件的數據類型。可用的符號常量有GL_BYTE, GL_UNSIGNED_BYTE, GL_SHORT,GL_UNSIGNED_SHORT, GL_FIXED, 和 GL_FLOAT,初始值爲GL_FLOAT。 normalized 指定當被訪問時,固定點數據值是否應該被歸一化(GL_TRUE)或者直接轉換爲固定點值(GL_FALSE)。 stride 指定連續頂點屬性之間的偏移量。若是爲0,那麼頂點屬性會被理解爲:它們是緊密排列在一塊兒的。初始值爲0。 pointer 指定第一個組件在數組的第一個頂點屬性中的偏移量。該數組與GL_ARRAY_BUFFER綁定,儲存於緩衝區中。初始值爲0;
經過glPixelStore能夠修改像素保存時對齊的方式。 像這樣: int alignment = 4; glPixelStorei(GL_UNPACK_ALIGNMENT, alignment); 第一個參數表示「設置像素的對齊值」,第二個參數表示實際設置爲多少。這裏像素能夠單字節對齊(實際上就是不使用對齊)、雙字節對齊(若是長度爲奇數,則再補一個字節)、四字節對齊(若是長度不是四的倍數,則補爲四的倍數)、八字節對齊。分別對應alignment的值爲1, 2, 4, 8。實際上,默認的值是4,正好與BMP文件的對齊方式相吻合。 glPixelStorei也能夠用於設置其它各類參數。
void glGenTextures (GLsizei n, GLuint *textures); //在數組textures中返回n個當期未使用的值,表示紋理對象的名稱 //零做爲一個保留的紋理對象名,它不會被此函數當作紋理對象名稱而返回 GLboolean glIsTexture (GLuint texture); //若是texture是一個已綁定的紋理對象名稱,而且沒有刪除,就返回GL_TRUE;
glActiveTexture && glBindTextureide
能夠這樣簡單的理解爲:顯卡中有N個紋理單元(具體數目依賴你的顯卡能力),每一個紋理單元(GL_TEXTURE0、GL_TEXTURE1等)都有GL_TEXTURE_1D、GL_TEXTURE_2D等,以下代碼:函數
struct TextureUnit { GLuint targetTexture1D; GLuint targetTexture2D; GLuint targetTexture3D; GLuint targetTextureCube; ... }; TextureUnit textureUnits[GL_MAX_TEXTURE_IMAGE_UNITS] GLuint currentTextureUnit = 0;
默認狀況下當前活躍的紋理單元爲0.ui
void glActiveTexture(GLenum textureUnit) { currentTextureUnit = textureUnit - GL_TEXTURE0 ; }
glActiveTextue 並非激活紋理單元,而是選擇當前活躍的紋理單元。this
void glBindTexture(GLenum textureTarget, GLuint textureObject) { TextureUnit *texUnit = &textureUnits[currentTextureUnit]; switch(textureTarget) { case GL_TEXTURE_1D: texUnit->targetTexture1D = textureObject; break; case GL_TEXTURE_2D: texUnit->targetTexture2D = textureObject; break; case GL_TEXTURE_3D: texUnit->targetTexture3D = textureObject; break; case GL_TEXTURE_CUBEMAP: texUnit->targetTextureCube = textureObject; break; } }
從示例代碼中能夠看到:當綁定紋理目標時,所做用的是當前活躍的紋理單元。指針
void glDrawElements( GLenum mode, GLsizei count, GLenum type, const GLvoid *indices); 其中: mode指定繪製圖元的類型,它應該是下列值之一,GL_POINTS, GL_LINE_STRIP, GL_LINE_LOOP, GL_LINES, GL_TRIANGLE_STRIP, GL_TRIANGLE_FAN, GL_TRIANGLES, GL_QUAD_STRIP, GL_QUADS, and GL_POLYGON. count爲繪製圖元的數量乘上一個圖元的頂點數。 type爲索引值的類型,只能是下列值之一:GL_UNSIGNED_BYTE, GL_UNSIGNED_SHORT, or GL_UNSIGNED_INT。 indices:指向索引存貯位置的指針。 glDrawElements函數可以經過較少的函數調用繪製多個幾何圖元,而不是經過OPENGL函數調用來傳遞每個頂點,法線,顏色信息。你能夠事先準備一系列分離的頂點、法線、顏色數組,而且調用一次glDrawElements把這些數組定義成一個圖元序列。當調用glDrawElements函數的時候,它將經過索引使用count個成序列的元素來建立一系列的幾何圖元。mode指定待建立的圖元類型和數組元素如何用來建立這些圖元。可是若是GL_VERTEX_ARRAY 沒有被激活的話,不能生成任何圖元。被glDrawElements修改的頂點屬性在glDrawElements調用返回後的值具備不肯定性,例如,GL_COLOR_ARRAY被激活後,當glDrawElements執行完成時,當前的顏色值是沒有指定的。沒有被修改的屬性值保持不變。