本节书摘来自华章出版社《OpenGL ES应用开发实践指南:Android卷》一 书中的第3章,第3.3节,作者:(美)Kevin Brothaler ,更多章节内容可以访问云栖社区“华章计算机”公众号查看。
3.3 把着色器一起链接进OpenGL的程序
既然我们已经加载并编译了一个顶点着色器和一个片段着色器,下一步就是把它们绑定在一起放入一个单个的程序(program)里。
3.3.1 理解OpenGL的程序
简单来说,一个OpenGL程序就是把一个顶点着色器和一个片段着色器链接在一起变成单个对象。顶点着色器和片段着色器总是一起工作的。没有片段着色器,OpenGL就不知道怎么绘制那些组成每个点、直线和三角形的片段;如果没有顶点着色器,OpenGL就不知道在哪里绘制这些片段。
我们知道顶点着色器计算屏幕上每个顶点的最终位置。我们也知道当OpenGL把这些顶点组织成点、直线和三角形并且分解成片段的时候,它就会向片段着色器询问每个片段最后的颜色。顶点和片段着色器一起合作生成屏幕上最终的图像。
虽然顶点着色器和片段着色器总是要一起工作,但并不意味着它们必须是一对一匹配的,我们可以同时在多个程序中使用同一个着色器。
让我们打开ShaderHelper,并在类的结尾加入如下代码:
与我们构建compileShader()所做的一样,我们也将一步一步地构建这个方法。它的大部分代码都在概念上与compileShader()相似。
3.3.2 新建程序对象并附上着色器
我们要做的第一件事情就是调用glCreateProgram()新建程序对象,并把那个对象的ID存进programObjectId。让我们加入如下代码:
这个语义同我们早前创建一个新的着色器对象是一样的:返回的整型值是程序对象的引用,如果对象创建失败,我们就会得到返回值0。
下一步就是附上着色器:
使用glAttachShader()方法把顶点着色器和片段着色器都附加到程序对象上。
3.3.3 链接程序
现在准备把这些着色器联合起来了,为此,将调用glLinkProgram(programObjectId):
为了检查这个链接是成功还是失败,我们会遵循编译着色器时所使用的步骤:
首先创建了一个新的整型数组来容纳这个结果,然后调用glGetProgramiv(programObjectId, GLES20.GL_LINK_STATUS, linkStatus, 0)把结果存入这个数组。我们也会检查这个程序的信息日志,这样,如果什么地方出错了或者OpenGL有些关于这个程序有用的内容,我们就能在Android的日志输出中看到:
3.3.4 验证链接状态并返回程序对象ID
现在需要检查链接状态:如果它是0,就意味着这个链接失败,这个程序对象将无法被使用,因此要把它删除并返回0给调用代码:
我们已经讲了这么多了,如果这个程序链接成功了,就可以在代码中使用它了。现在完成了,因此让我们返回这个新的程序对象给调用代码:
3.3.5 给渲染类加入代码
既然我们已经有代码把这些着色器链接在一起了,让我们继续,从程序中调用它。首先在AirHockeyRenderer的顶部加入如下成员变量:
这个整型值用来存储那个链接的程序的ID。在onSurfaceCreated()的结尾处加入如下代码把着色器链接起来:
现在也许该拿起一杯咖啡,让你的大脑休息片刻了。在下一节,我们将开始做最后的拼接,并把数据链接到OpenGL。