[OpenGL] glVertexAttribPointer函數與glVertexAttribIPointer函數使用中遇到的小坑(int類型被自動轉換為float類型)


起因:用OpenGL ES的變換反饋(transform feedback)特性,在GPU上實現圖象處理中常用的查表映射功能(LookUp Table Map)。

 

這是一個工作量在五天以內的小項目(簡單分為三個部分:一、分配頂點數組,二、寫着色器,三、利用變換反饋把結果取回內存。)

本應該自己來做。但是湊巧有個算法移植到CUDA平台的工作在手,於是就拜托公司一位比較熟悉OpenGL ES的實習生來做,先第一部分和第三部分,第二部分可以暫時以一個簡單的着色器來替代,先把整個框架搭起來。

 

過了三天,自己手頭的事情做好了。就問他做的怎么樣,有沒有遇到什么問題。小伙子說,框架搭好了,但是遇到了一個百思不得其解的問題,傳進去着色器的-1,沒做任何改變,純粹地返回,但是在讀出來的時候總是-1082130432。(其中int類型的數字-1是表中較常出現的數字。)

 

簡單review了一下,代碼大致沒什么問題。

 

排查-1變成-1082130432的問題。

 

用以下代碼測試

float f = -1.0f;

printf("%d\n", *(int*)&f);

得到的輸出結果就是-1082130432。

所以很明顯,在傳入着色器的過程當中,int類型的-1被轉化成了float類型的-1,所以我們在讀取以int類型再去讀取它的時候,就讀出了-1082130432這個數字。

bug定位好了之后,就開始排查數據進入着色器的過程中是否出現了問題。

 

最后發現,小伙子用了glVertexAttribPointer函數來指定每個頂點的屬性,但是這個函數在normalized屬性被設置為GL_FALSE時,非float類型的數值將被轉換成float類型。於是int類型的-1就被轉換成了float類型。

改用glVertexAttribIPointer函數,bug解決。

 

OpenGL ES 3中的glVertexAttribPointer與glVertexAttribIPointer的文檔摘錄如下:

For glVertexAttribPointer, if normalized is set to GL_TRUE, it indicates that values stored in an integer format are to be mapped to the range [-1,1] (for signed values) or [0,1] (for unsigned values) when they are accessed and converted to floating point. Otherwise, values will be converted to floats directly without normalization.

For glVertexAttribIPointer, only the integer types GL_BYTEGL_UNSIGNED_BYTEGL_SHORTGL_UNSIGNED_SHORTGL_INTGL_UNSIGNED_INT are accepted. Values are always left as integer values.

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM