我的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