概述
- 当你要求OpenGL ES
编译
和链接着色器
时, 思考 OpenGL ES 实现 必须要做的事情; 着色器代码
通常解析为某种中间表现形式
, 这和大部分编译语言
相同(例如,抽象语法树
);编译器
必须将抽象表现形式
转化为硬件的机器指令
。 理想状态下, 这个编译器
还应该进行大量的优化
, 例如无用代码删除、常量传播
等; 进行这些工作需要付出代价——主要是CPU时间
和内存
;- OpenGL ES 3.0 实现
必须支持
在线着色器编译
(用glGetBooleanv
检索GL_SHADER_COMPILER
值必须是GL_TRUE
); - 可以指定着色器使用
glShaderSource
; - 可以尝试缓解
着色器编译
对资源的影响; 一旦完成了应用程序中着色器的编译, 就可以调用void glReleaseShaderCompiler(void)
; 这个函数提示 OpenGL ES,我们已经完成了着色器编译器
的工作, 可以释放它的资源了; 不过注意, 这个函数只是一个提示, 如果决定用glCompileShader
编译更多
的着色器
, 那么OpenGL ES需要重新为编译器分配资源
。
程序二进制码
程序二进制码
是完全 编译和链接的 程序
的二进制表现形式
。- 可以保存到
文件系统
供以后使用,避免在线编译
的代价; - 如果使用
程序二进制码
,就不用在实现中分发着色器源代码
; - 可以在成功地
编译和链接程序 之后
, 使用glGetProgramBinary
检索程序二进制代码
:
- 检索了
程序二进制代码
之后, 可以用glProgramBinary
将其保存到文件系统
, 或者将程序二进制代码
读回OpenGL ES
实现:
程序二进制码的兼容问题处理
OpenGL ES 规范
不强制使用任何特定的二进制格式
; 相反,二进制格式
完全取决于供应商
; 即程序的可移植性
比较差
, 但是意味着供应商
可以创建较不笨重
的OpenGL ES 3.0实现
;- 实际上,
二进制格式
在同一供应商
的不同驱动程序版本中
的实现
可能出现变化
; 为了确保
是存储的程序二进制代码
仍然兼容
, 在调用glProgramBinary
之后, 可以通过glGetProgramiv
查询GL_LINK_STATUS
, 如果二进制码
不再兼容
, 则须重新编译
着色器源代码。
参考自:
- 《OPENGL ES 3.0编程指南(第2版)》