overview
- 用
glCreateShader
创建一个shader,可以指定shader的类型等信息。 - 通过
glShaderSource
导入shader的源文件。 - 通过
glCompileShader
编译指定的shader。 - 通过
glCreateProgram
创建一个program。 - 通过
glAttachShader
来将一对shader绑定到一个program中。 - 通过
glLinkProgram
来将这对shader链接到该program中。 - 通过
glUseProgram
来使用该program。 - 如果shader使用了默认的uniform块,用
glGetUniformLocation
来查询uniform变量的地址,并且通过glUniform
来设置它们的值。 - 如果shader使用了命名的uniform块,用
glGetUniformBlockIndex
和glGetActiveUniformBlockiv
来查询该uniform块的信息。查询uniform块中uniform变量的偏移值是通过glGetActiveUniformsiv
来得到的。uniform块和绑定一些点(points)的buffer object的关联是通过glUniformBlockBinding
来完成的。且,buffer object到这些点的绑定是通过glBindBufferRange
来完成的。 - 如果vertex shader使用了用户定义的变量,application必须提供之,这是通过opengl api的调用来定位vertex attribute位置的。在一个vertex shader中,在这些属性数据被传给shader之前,泛型顶点属性的索引应该和一个变量相关联,这通常有2种方法。application可以显式创建之,通过在链接(linking)之前调用
glBindAttribLocation
。或者,如果没有显式的关联被创建,opengl会在linking这步自动关联。一个application可以查询这种关联,通过调用glGetAttribLocation
。所以,泛型的顶点属性可以通过glVertexAttrib
来传递给vertex shader;或者使用glVertexAttribPointer
和glEnableVertexArrayPointer
结合标准的opengl命令来描画vertex arrays。 - 如果fragment shader使用了用户定义的输出(out)变量,application可能要创建用户定义的变量和fragment数据索引之间的关联,这通过在linking前调用
glBindFragDataLocation
来完成。或者,如果没有显式的关联,opengl会在linking时自动进行关联。一个application可以查询赋值,通过glGetFragDataLocation
。 - 一个application可能选择性地记录vertex shader的输出(out)变量到一个或多个可以tranform feedback的buffer。在vertex shader输出变量被记录前,vertex shader输出变量通过
glTransformFeedbackVarying
和绑定一些点的feedback buffer相关联;且buffer对象和这些点的绑定是通过glBindBufferRange
来完成的。
1. obtaining version information
OpenGL和OpenGL shading language的版本号均可通过glGetString
来获得。
void getGlVersion(int *major, int *minor) {
const char *verstr = (const char *) glGetString(GL_VERSION);
if ((verstr == NULL) || (sscanf(verstr, "%d.%d", major, minor) != 2))
{
*major = *minor = 0;
fprintf(stderr, "Invalid GL_VERSION format!!!\n");
}
}
void getGlslVersion(int *major, int *minor) {
int gl_major, gl_minor;
getGlVersion(&gl_major, &gl_minor);
*major = *minor = 0;
if (gl_major == 1)
{
const char *extstr = (const char *) glGetString(GL_EXTENSIONS);
if ((extstr != NULL) &&
(strstr(extstr, "GL_ARB_shading_language_100") != NULL))
{
*major = 1;
*minor = 0;
}
}
else if (gl_major >= 2)
{
const char *verstr = (const char *) glGetString(GL_SHADING_LANGUAGE_VERSION);
if ((verstr == NULL) ||
(sscanf(verstr, "%d.%d", major, minor) != 2))
{
*major = *minor = 0;
fprintf(stderr, "Invalid GL_SHADING_LANGUAGE_VERSION format!!!\n");
}
}
}
2. creating shader objects
创建shader的函数原型:
GLuint glCreateShader(GLenum shaderType) // GL_VERTEX_SHADER/GL_FRAGMENT_SHADER
然后指定shader的源文件:
void glShaderSource(GLuint shader, GLsizei count, // 源码字符串数组的个数 const GLchar **string