iOS代码
/*
*
* VertexShader-用于渲染形状的顶点的OpenGLES 图形代码。
* FragmentShader-用于渲染形状的外观(颜色或纹理)的OpenGLES 代码。
* Program-一个OpenGLES对象,包含了你想要用来绘制一个或多个形状的shader。
*
*/
// 创建program
+ (GLuint)createAndLinkProgramWith:(GLuint)vsHandle fsHandle:(GLuint)fsHandle attrs:(NSArray*)attrs {
//创建一个空的OpenGL ES Program
GLuint programHandle = glCreateProgram();
if (programHandle != 0) {
// 将vertex shader添加到program
glAttachShader(programHandle, vsHandle);
// 将fragment shader添加到program
glAttachShader(programHandle, fsHandle);
if (attrs != nil) {
for (int i = 0; i < attrs.count; i++) {
//把program的顶点属性索引与顶点shader中的变量名进行绑定
glBindAttribLocation(programHandle, i, [[attrs objectAtIndex:i] UTF8String]);
}
}
GLint status;
// 创建可执行的 OpenGL ES program
glLinkProgram(programHandle);
// glValidateProgram(programHandle);
// 获取program对象的参数值
glGetProgramiv(programHandle, GL_LINK_STATUS, &status);
if (status == GL_FALSE){
if (vsHandle) glDeleteShader(vsHandle);
if (fsHandle) glDeleteShader(fsHandle);
programHandle = 0;
}
}
assert(programHandle != 0);
return programHandle;
}
安卓代码
private int createProgram(String vertexSource, String fragmentSource)
{
// 加载顶点着色器
int vertexShader = loadShader(GLES20.GL_VERTEX_SHADER, vertexSource);
if (vertexShader == 0)
{
return 0;
}
// 加载片元着色器
int pixelShader = loadShader(GLES20.GL_FRAGMENT_SHADER, fragmentSource);
if (pixelShader == 0)
{
return 0;
}
// 创建着色器程序
int program = GLES20.glCreateProgram();
// 若程序创建成功则向程序中加入顶点着色器与片元着色器
if (program != 0)
{
// 向程序中加入顶点着色器
GLES20.glAttachShader(program, vertexShader);
// 向程序中加入片元着色器
GLES20.glAttachShader(program, pixelShader);
// 链接程序
GLES20.glLinkProgram(program);
// 存放链接成功program数量的数组
int[] linkStatus = new int[1];
// 获取program的链接情况
GLES20.glGetProgramiv(program, GLES20.GL_LINK_STATUS, linkStatus, 0);
// 若链接失败则报错并删除程序
if (linkStatus[0] != GLES20.GL_TRUE)
{
Log.e(TAG, "Could not link program: ");
Log.e(TAG, GLES20.glGetProgramInfoLog(program));
GLES20.glDeleteProgram(program);
program = 0;
}
}
// 释放shader资源
GLES20.glDeleteShader(vertexShader );
GLES20.glDeleteShader(pixelShader);
return program;
}
1. glCreateProgram
在连接shader之前,首先要创建一个容纳程序的容器,称为着色器程序容器。可以通过glCreateProgram函数来创建一个程序容器。
函数原型:
int glCreateProgram ()
如果函数调用成功将返回一个正整数作为该着色器程序的id。
2.glAttachShader
接下来,我们要将shader容器添加到程序中。这时的shader容器不一定需要被编译,他们甚至不需要包含任何的代码。我们要做的只是将shader容器添加到程序中。使用glAttachShader函数来为程序添加shader容器。
函数原型:
void glAttachShader (int program, int shader)
参数含义:
program是着色器程序容器的id;
shader是要添加的顶点或者片元shader容器的id。
3. glLinkProgram
链接程序。
函数原型:
void glLinkProgram (int program)
参数含义:
program是着色器程序容器的id。
在链接操作执行以后,可以任意修改shader的源代码,对shader重新编译不会影响整个程序,除非重新链接程序。
4.glUseProgram
加载并使用链接好的程序。
函数原型:
void glUseProgram (int program)
参数含义:
program是要使用的着色器程序的id。
如果将program设置为0,表示使用固定功能管线。如果程序已经在使用的时候,对程序进行重新编译,编译后的应用程序会自动替代以前的那个被调用,这时你不需要再次调用这个函数。