我的OpenGL学习进阶之旅着色器编译器和程序二进制码

Posted 欧阳鹏

tags:

篇首语:本文由小常识网(cha138.com)小编为大家整理,主要介绍了我的OpenGL学习进阶之旅着色器编译器和程序二进制码相关的知识,希望对你有一定的参考价值。

一、着色器编译器

当你要求OpenGL ES 编译和链接着色器的时候,光花一点时间思考OpenGL ES 必须实现做到的事情。

着色器代码通常解析为某种中间表现形式,这和大部分编程语言相同(例如,抽象语法树)。

编译器必须将抽象表现形式转换为硬件的机器指令。

理想情况下,这个编译器还应该进行大量优化,例如无用代码删除、常量传播等。进行这些工作需要付出代价------主要是CPU时间和内存。

OpenGL ES 3.0 必须支持在线着色器编译(用 glGetBooleanv检索 GL_SHADER_COMPILER值必须是GL_TRUE)。

  • 你可以指定着色器使用glShaderSource,就像我们在前面博客示例中所做的一样。
  • 你还可以尝试缓解着色器编译对资源的影响。也就是说,一旦完成了应用程序中着色器的编译,就可以调用glReleaseShaderCompiler。这个函数提示OpenGL ES实现已经完成了着色器编译器的工作,可以释放它的资源了。注意,这个函数只是一个提示,如果决定用glCompileShader编译更多的着色器,那么OpenGL ES 实现需要重新为编译器分配资源。
void glReleaseShaderCompiler (void);

提示OpenGL ES实现已经完成了着色器编译器的工作,可以释放它的资源了。因为这个函数只是个提示,所以有些实现可能忽略对这个函数的调用。

二、程序二进制码

程序二进制码 是完全编译和链接的程序的二进制表现形式。

它们很有用,因为可以保存文件系统供以后使用,从而避免在线编译的代价。你也可以使用程序二进制码,这样就没有必要在实现中分发着色器源代码。

2.1 glGetProgramBinary

你可以在成功编译和链接程序之后,使用glGetProgramBinary检索程序二进制码。

void glGetProgramBinary (GLuint program, GLsizei bufSize, 
						GLsizei *length, GLenum *binaryFormat, 
						void *binary);


参数说明:

  • program
    程序对象句柄
  • bufSize
    可以写入binary的最大字节数
  • length
    二进制数据的字节数
  • binaryFormat
    供应商专用二进制格式标志
  • binary
    着色器编译器生成的二进制数据指针

2.2 glProgramBinary

当你检索了程序二进制码之后,可以使用glProgramBinary将其保存到文件系统,或者将程序二进制码读回OpenGL ES实现。

void glProgramBinary (GLuint program, GLenum binaryFormat,
 						const void *binary, GLsizei length);


参数说明:

  • program
    程序对象句柄
  • binaryFormat
    供应商专用二进制格式标志
  • binary
    着色器编译器生成的二进制数据指针
  • length
    二进制数据的字节数

OpenGL ES规范不强制使用任何特定的二进制格式;相反,二进制格式完全取决于供应商。 这明显意味着,程序的可移植性较差。 但是也意味着 供应商可以创建较不笨重的OpenGL ES 3.0实现

实际上,二进制格式在同一供应商的不同驱动程序版本中的实现可能变化。为了确保存储的程序二进制码仍然兼容,在调用glProgramBinary 之后,可以通过glGetProgramiv查询GL_LINK_STATUS。如果二进制码不再兼容,你必须重新编译着色器源代码。

以上是关于我的OpenGL学习进阶之旅着色器编译器和程序二进制码的主要内容,如果未能解决你的问题,请参考以下文章

我的OpenGL学习进阶之旅如何抽取着色器代码到assets目录下的GLSL文件,以及如何通过Java或者C++代码来加载着GLSL文件?

我的OpenGL学习进阶之旅着色器和程序(上)------着色器

我的OpenGL学习进阶之旅着色器和程序(上)------着色器

我的OpenGL学习进阶之旅着色器和程序(下)------ 程序对象

我的OpenGL学习进阶之旅着色器和程序(下)------ 程序对象

我的OpenGL学习进阶之旅解决着色器编译错误:#version directive must occur on the first line of the shader