程序对象是一个容器对象,可以将着色器与之连接,并链接一个最终的可执行程序。
1、GLuint glCreateProgram();
作用:创建一个程序对象,没有参数,返回一个指向新程序对象的句柄
2、void glDeleteProgram(GLuint program);
作用:通过句柄删除程序对象
3、void glAttachShader(GLuint program ,GLuint shader);
作用:将着色器对象连接到给定程序。在Opengl ES3.0 中,每个程序对象必须连接一个顶点着色器和一个片段着色器。
program --- 指向程序对象的句柄
shader ---- 指向程序连接的着色器对象的句柄
注意:着色器可以在任何时候连接,在连接到程序前不一定需要编译,甚至可以没有源代码。唯一要求是,每个程序对象必须有且只有一个顶点着色器和片段着色器与之连接。
4、void glDetachShader(GLuint program,GLuint shader);
作用:断开着色器的连接
program --- 指向程序对象的句柄
shader --- 指向程序要断开连接的着色器对象的句柄
5、void glLinkProgram(GLuint program);
作用:链接程序对象
program 指向程序对象句柄
链接操作负责生成最终的可执行程序。链接程序将检查各种对象的数量,确保成功链接。
链接程序将确保顶点着色器写入片段着色器使用的所有顶点着色器输出变量。链接程序还将确保任何在顶点和片段着色器中都声明的统一变量和统一变量缓冲区的类型相符。链接程序还需确保最终的程序符合具体实现的限制(如:属性,统一变量或者输入输出着色器变量的数量)。
6、void glGetProgramiv(GLuint program,GLenum pname,GLint * params);
作用:检查链接是否成功。
program --- 需要获取信息的程序对象句柄
pname --- 获取信息的参数
GL_LINK_STATUS --- 检查链接是否成功
GL_ACTIVE_ATTRIBUTES --- 返回顶点着色器中活动属性的数量
GL_ACTIVE_ATTRIBUTE_MAX_LENGTH --- 返回最大属性名称的最大长度(以字符表示)。可用于确定存储属性名字符串所需的内存量
GL_ACTIVE_UNIFORMS ---返回活动统一变量的数量
GL_ACTIVE_UNIFORMS_MAX_LENGTH -- 返回活动最大统一变量名称的最大长度
GL_ATTACHED_SHADERS --- 可获得连接到程序对象的着色器数量
GL_DELETE_STATUS --- 查询返回程序对象是否已经被标记为删除
GL_INFO_LOG_LENGTH --- 查询程序对象 存储的信息日志长度
GL_TRANSFORM_FEEDBACK_BUFFER_MODE ---返回GL_SEPARATE_ATTRIBS 或GL_INTERLEAVED_ATTRIBS
表示变换反馈启用时的缓冲区模式
GL_TRANSFORM_FEEDBACK_VARYINGS
GL_TRANSFORM_FEEDBACK_VARYING_MAX_LENGTH --- 分别返回程序的变化反馈模式中的输出变量数量和输出变量名称的最大长度
GL_ACTIVE_UNIFORM_BLOCKS
GL_ACTIVE_UNIFORM_BLOCK_MAX_LENGTH ---返回活动统一变量的程序中的统一变量块数量和统一变量块名称的最大长度
GL_PROGRAM_BINARY_RETRIEVALBE_HINT --- 返回一个表示程序目前是否启用二进制检索指示的值
GL_VALIDATE_STATUS --- 查询最后一个校验操作的状态
params --- 指向查询结果整数存储位置的指针
6、void glGetProgramInfoLog(GLuint program,GLsizei maxLength,GLsizei * length,GLchar * infoLog);
作用:从程序的信息日志中获取信息
program --- 指向需要获取信息的程序对象的句柄
maxlenght --- 存储信息日志的缓冲区大小
length --- 写入的信息日志长度(减去null终止符)。若不想知道长度,参数可设置为NULL
infoLog --- 指向存储信息日志的字符缓冲区的指针
7、void glValidateProgram(GLuint program);
作用:检查程序能否以当前状态执行
program --- 需要校验的程序对象的句柄
8、void glUseProgram(GLuint program);
作用:渲染前,将其设置为活动程序
program --- 设置为活动程序的程序对象句柄
示例程序:
bool EsUtils::checkGlError(const char* funcName) { GLint err = glGetError(); if (err != GL_NO_ERROR) { ALOGE("GL error after %s(): 0x%08x\n", funcName, err); return true; } return false; }
GLuint EsUtils::createProgram(const char* vtxSrc, const char* fragSrc) { GLuint vtxShader = 0; GLuint fragShader = 0; GLuint program = 0; GLint linked = GL_FALSE; vtxShader = createShader(GL_VERTEX_SHADER, vtxSrc); if (!vtxShader) goto exit; fragShader = createShader(GL_FRAGMENT_SHADER, fragSrc); if (!fragShader) goto exit; program = glCreateProgram();//创建着色器程序 if (!program) { checkGlError("glCreateProgram"); goto exit; } glAttachShader(program, vtxShader);//向程序中加入顶点着色器 glAttachShader(program, fragShader);//向程序中加入片元着色器 glLinkProgram(program);//链接程序 glGetProgramiv(program, GL_LINK_STATUS, &linked);//获取program的链接情况 if (!linked) { ALOGE("Could not link program"); GLint infoLogLen = 0; glGetProgramiv(program, GL_INFO_LOG_LENGTH, &infoLogLen); if (infoLogLen) { GLchar* infoLog = (GLchar*)malloc(infoLogLen); if (infoLog) { glGetProgramInfoLog(program, infoLogLen, NULL, infoLog); ALOGE("Could not link program:\n%s\n", infoLog); free(infoLog); } } glDeleteProgram(program); program = 0; } exit: glDeleteShader(vtxShader); glDeleteShader(fragShader); return program; }