你們好,我是程序員kenney,今天給你們分析一下OpenGL
的黑屏常見緣由。java
作OpenGL
開發的同窗,想必必定碰到過黑屏的問題,特別是剛接觸OpenGL
的同窗,可能會以爲黑屏問題讓人至關頭疼,由於OpenGL
的查錯沒有通常編程時那麼簡單,咱們一般是利用glGetError()
這個API
來獲取錯誤碼,但這個方法獲取的錯誤是調用這個方法時,已經產生的錯誤,它有多是好久以前產生的,這樣查越來仍是比較不方便的,並且,有些黑屏的狀況下,glGetError()
也不會報任何錯。程序員
在給你們總結常見的黑屏緣由以前,咱們先來了解一下咱們看到的黑屏到底是什麼?其實屏幕也是一塊frame buffer
,但它比較特殊,是0
號frame buffer
,咱們若是本身申請frame buffer
的話,獲得的id
是大於0的。那麼frame buffer
它就會有本身的顏色,若是不特地設置的話,它就是黑色的,所以若是咱們渲染操做未正確執行,什麼也沒渲染出來,天然看到了底色的黑色。編程
咱們也能夠經過glClearColor()+glClear()
來設置消除顏色及執行消除操做,來將一個frame buffer
清成某種顏色。所以,若是你將frame buffer
清成了別的顏色,但其它渲染操做未正確執行,你有可能也不是黑屏,而是你設置的消除顏色,這裏也一併總結了,統成爲黑屏,同時也包括其它一些不正確的情形。數組
下面給你們總結一下:post
調用線程不正確線程
OpenGL
的API
在調用時須要有正確的上下文,在Android
中稱爲EGL Context
,其它平臺有其它平臺的叫法,但原理相似。一個線程須要跟EGL Context
綁定才能正確使用OpenGL
的API
,不然調用不會有任何效果,具體可參考個人一篇文章:《OpenGL ES 高級進階:EGL及GL線程》。code
GL Program
不正確開發
OpenGL
渲染須要經過GL Program
,它就是一個程序,和咱們的普通程序是一個道理,只不過它是運行在GPU
上的,若是它不正確了,那天然就渲染不出正確的結果,常見的不正確緣由爲shader
編譯失敗,一般是由於語法錯誤,能夠用glGetShaderInfoLog()
來在編譯以後查看相關shader
信息,以及在Link
後用glGetProgramInfoLog()
查看相關program
信息,若是獲得的信息爲空,則說明沒有錯。get
未調用glDrawXXX()
it
要渲染出來東西,必須調用glDrawXXX()
,通常不多出現沒調的狀況,通常都是低級失誤,最好也排查一下。
頂點attribute
值設置錯誤
頂點關係到渲染到什麼位置,若是設置錯誤致使渲染的位置在可視範圍以外,那麼就看不到了,等於沒作渲染。
attribute
未啓用
咱們經過想要設置一個attribute
的值,須要獲取這個attribute
的location
,並經過glVertexAttribPointer()
給它設置值,但別忘了須要使用glGetAttribLocation()
來啓用這個location
,否則設置了也沒有用,默認是不啓用的。
View Port
設置錯誤
View Port
即視口,能夠理解成咱們經過一個窗口去看見OpenGL
世界座標系裏渲染的景物,就像咱們經過窗口看到室外的景物同樣,若是這個窗口沒設置或者設置不正確,也會致使看不到東西,通常狀況下,咱們會將它設置爲surface
的大小,這樣渲染出來的東西就恰好填滿這個surface
。
沒有渲染到0
號frame buffer
有時候渲染操做有不少步,想作完這些步驟後,再將作好的結果顯示的屏幕上,這時就會用一些frame buffer
來作離屏渲染,但在最後一步渲染到屏幕上時,須要將frame buffer
綁定回0
號,才能上屏。
渲染了一個不正確的紋理
例如咱們但願對一個紋理作一些處理而後渲染出來,但若是這個紋理自己是不正確的,例如前面的步驟出了一些錯,致使給過來的紋理id
不正確,好比是0
,或者紋理id
是正確的,但這個紋理是全黑的或者空的,也會致使黑屏。
glDrawXXX()
方法傳遞的頂點數不正確
咱們在調用glDrawXXX()
,會設置頂點數組的開始位置和數量,若是設置不正確,致使傳遞的頂點是0
個,也會致使渲染不出來任何東西。
頂點buffer
的position
不正確
這一點主要是針對java
及kotlin
,glVertexAttribPointer()
接受數據時是經過一個buffer
,而咱們往buffer
是put
數據後,buffer
的position
會相應地日後移動,所以在調用glVertexAttribPointer()
以前,記得將position
設回到0
,不然它將從末尾開始取數據,固然就取不到了。
未開啓顏色混合渲染了有透明度的紋理
OpenGL
默認是不開啓顏色混合的,這會致使透明的部分一般會被渲染成黑色,而不是透出下面的顏色,具體能夠參數個人一篇文章:《OpenGL ES 高級進階:顏色混合》。
好了,先總結到這,這些是比較常見的,也歡迎你們給我留意補充討論~
感謝閱讀!