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做法,當然部分顯卡驅動廠商也是這麼做的。