1 问题
左图是出问题的,白色顶面显示异常;右图是标准的。看症状是顶部白色没了。想不通,ios上这些平台都没问题。。x64的代码出问题,看代码也没有特别的指针,int强转之类的风险,只能搭环境。
2 AS上搭建环境
AS工程,真是折腾:
- 网络问题,很多组件动态拉取,经常这次ok下次启动可能就一堆问题,
- gradle版本问题,android sdk,jdk,ndk版本问题,
能不能像VS,XCode学习下,离线安装直接使用多好。工程搞好了,创建了x86_64的模拟器,真的刷新了对android的好感,模拟器居然会这么快。。官方说明x86系列的 比arm系列快十倍多。
排查过程:
- 顶部闪烁,是不是重叠面导致;--> 单独把顶面拉高,没看到有重叠面;(视频里就是抬高后的效果)
- 只画顶部的内容,还是闪烁,
- 进一步,只画填充,不画3D border,此时正常了。。。跟border绘制的时候属性数据状态串了。
3Dborder和polygon是两个shader,居然能串了顶点属性,带着疑惑再去看代码,看到了一些奇怪的写法,搞了这么多年gl(太gler了,始终无暇顾及vulkan&metal)很少见的写法:
pProgram->setUniformMat4f("MVP", mOrigin.matrixMVP());
if (isColorValid())
pProgram->setVertexAttrib4f("color", mColor);
if (isCreateRenderUnit){
pRenderSystem->drawRenderUnit(mpRenderUnit);
} else {
drawDirectly();
}
在drawcall之前使用setVertexAttrib4f,居然是批量传递顶点颜色,drawcall的调用只是传递了位置列表。虽然programe中指定了attribute是color+position,setAttributeDefaultValue函数会把color对应的slot关闭。。
简而言之,奇怪的做法是:像传递uniform一样批量传递attribute数据。。只是为了减少vbo的大小,或者drawDirectly的传递数据量。
查看影响范围,居然有好几处都这么用了。ios/android上居然一直没问题。
解决方法
- 改造shader,color改成uniform vec4,
- 改造MeshPolygonOnGround的buffer建模过程,采用标准的color|position作为顶点属性组生成VBO。
后者更优,范围可控。
3 结束
去网上找理论依据,看到这么一段话:
其中glVertexAttrib1f和glVertexAttrib1fv会加载(x, 0.0, 0.0, 1.0),glVertexAttrib2f和glVertexAttrib2fv会加载(x, y, 0.0, 1.0),glVertexAttrib3f和glVertexAttrib3fv会加载(x, y, z, 1.0),glVertexAttrib4f和glVertexAttrib4fv会加载(x, y, z, w)。在实际中,常量顶点属性提供了和uniform等价的功能,两者都可以选用。
虽然两种做法功能等价,但是实际适配和大众认知情况还是倾向于uniform做法,当然部分显卡驱动厂商也是这么做的。