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执行完成时,当前的颜色值是没有指定的。没有被修改的属性值保持不变。