android x64平臺適配的渲染異常的問題

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 結束

去網上找理論依據,看到這麼一段話:

其中glVertexAttrib1fglVertexAttrib1fv會加載(x, 0.0, 0.0, 1.0),glVertexAttrib2fglVertexAttrib2fv會加載(x, y, 0.0, 1.0),glVertexAttrib3fglVertexAttrib3fv會加載(x, y, z, 1.0),glVertexAttrib4fglVertexAttrib4fv會加載(x, y, z, w)。在實際中,常量頂點屬性提供了和uniform等價的功能,兩者都可以選用。

雖然兩種做法功能等價,但是實際適配和大衆認知情況還是傾向於uniform做法,當然部分顯卡驅動廠商也是這麼做的。

發佈了218 篇原創文章 · 獲贊 94 · 訪問量 95萬+
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章