OpenGL ES 着色器中问题解决技巧
太阳火神的美丽人生 (http://blog.csdn.net/opengl_es)
本文遵循“署名-非商业用途-保持一致”创作公用协议
灰暗的一天,
终于见到一丝曙光,
心情终于从沉重变得略有轻松,
虽然,
一早就明白,
曙光终究会闪现,
也至少,
这仅有的一丝,
足以照亮前进的信念,
心中充满力量!
开场白结束,下面来看看是个什么技巧。
原来以为着色器语言象早些年调试 javascript 一样,只能靠语法来保障其在宿主语言中的正确逻辑,
刚才发现,始终无法呈现模型时,Xcode 的日志区居然有一堆输出内容,
细看才注意到,这里面有着色器中声明的变量名,写着找不到指定的变量名。
我的......
原来,着色器语言也会输出日志,我以为它是运行在 GPU 中,是不会在 CPU 端输出内容的!
也许这种想法本身就是对的,
只是太过偏置于这种想法,而忽略了一个问题,
模拟器上运行,可能是用的软件的 GPU ,
另外,也可能是调用 OpenGL ES API 编译着色器程序时,是运行在 CPU 上的,
这个真心不太了解其内部运行机理,
无从猜测,这个到底运行在哪儿,
但至少已经明确地看到,变量类问题,是会在 XCode 中输出日志的,
那么有一部分这样的问题,就是可以调试的了。
至于其它的问题,还不太清楚,至少这里可以扩展成是着色器脚本中的语言错误,应该是能在编译或运行阶段得以日志输出解决,而且是自动的噢!
// 投影矩阵 uniform mat4 uProjectionMatrix; // 视图模型矩阵 uniform mat4 uModelViewMatrix; // 法向矩阵 uniform mat3 uNormalMatrix; // 顶点坐标:只能作为局部变量声明 attribute vec4 aPositionCoordinate; // 纹理坐标:只能作为局部变量声明 attribute vec2 vTextureCoordinate; // 输出到片元着色器的光源颜色 varying vec4 vDestinationColor; // 输出到片元着色器的纹理坐标 varying vec2 vTextureCoordOut; void main(void) { gl_Position = uProjectionMatrix * uModelViewMatrix * aPositionCoordinate; // ...... vDestinationColor = vec4(color+color+color, 1); vTextureCoordOut = aTextureCoordinate; }
看到这里的纹理坐标变量 vTextureCoordinate 了吗,最后一行赋值时使用的确是 a TextureCoordinate,
总是被这种不是问题的问题困挠,真是无耐。
2014-01-02 20:42:58.425 Tutorial12[71172:70b] Error compiling shader: ERROR: 0:57: Use of undeclared identifier 'aTextureCoordinate' 2014-01-02 20:42:58.426 Tutorial12[71172:70b] >> Error: Failed to setup program.
不过,只能解决着色器内部的问题,至于宿主语言与着色器之间的变量传递,要你来确保变量名与类型以及该类型对应 API 的正确对应了。
另外,着色器中变量命名最好遵循以下原则:
1、局部变量以 a 开头;
2、全局变量以 u 开头;
3、参数变量以 v 开头;
4、宿主语言中的槽位变量以对应的着色器变量后加 Slot 结尾;
为什么?如果你懂着色器语言以及API的应用,你是应该知道的,如果着色器语言没学好,那就自个儿猜去吧,算是一个动力,逼着你好好学一下着色器语言的基础。
我学了好同遍了,还有好多没明白!
这一年多,养成了所谓的快速开发习惯(敏捷开发实施得“更敏捷”之后的奇怪产物),真是坑人不浅,经常会出现这种怪问题,不是问题的问题,耽误很多时间,扰乱正常的思维。
是时侯,放慢脚步,把这种可恶的习惯清除的时侯了,
放慢脚步,按步就班,起初是有些慢,但越走越快,因为加速度始终是正的;不能再出现这种刚开始加速度赶飞机了,越往后,加速度越低,很快变成负值的问题。
敏捷开发,不是要放弃很多东西,而是要把目标设的近些而已,也即只考虑眼前的一块为天,但麻雀虽小,五脏俱全,而不是为了飞得快,把肠子都掏出来,这种可笑的做法,结果人人皆知,最后连开发者自已都收拾不了,别人更没办法去收拾了。
提纲挈领,即使是巴张大的渔网,都得这样才能拿得顺利,否则就会乱成一团,这样的渔网,你再也提不起来,摘不清了,即使弄到了鱼,也只能捏碎了再拿出来。
不信?那你就去买一张渔网来试试喽!