2012-11-28 25 views
2

(如何)可以標強制轉換爲另一種標而不GLSL轉換?(How)可以在GLSL中將標量轉換爲另一個標量嗎?

在這個問題中使用的「cast」的定義是在不改變數據本身的情況下改變對完全相同數據的解釋,假設這兩種類型具有相同的位數。即(float)B00101111 == B00101111

在這個問題中使用的「轉換」的定義是改變數據的解釋以及將所述數據重新格式化爲原始值的一些數學近似,即(float)1 == 1.0

5.4.3 GLSL 4.30.6規範意味着標量float-to-int和int-to-float構造函數只執行轉換: 「當使用構造函數將任何浮點類型轉換爲一個整數類型, 浮點值的小數部分被刪除。「 - 頁碼。 87

在棺材的另一種釘與此行中第5.1節,第85: 「沒有類型轉換操作;構造器被用來代替」。

的目標是使用一個緩衝區紋理/紋理緩衝和texelFetch(...),以獲得浮vec4s(128位)和填充結構如:

struct MyStruct 
{ 
int foo; //32bit 
float bar; //32bit 
int baz; //32bit 
short blah; //16bit 
short hmm; //16bit 
} // 128bit total 

...但如何將vec4分解成二進制子塊並將其重新轉換爲設置所述結構值存在問題。

請問以下,理論上的工作?

MyStruct myUuberChunk = MyStruct(myVec4); 

背後使用浮動vec4s(或INT爲此事vec4s),等待它是正確的理由,是爲了得到一個128位的所有值取帶寬性能的目的(多數卡有4個32位內存總線)。

回答

6

理論上是否會起作用?

GLSL不允許直接重新詮釋結構。雖然GLSL(3.30+)確實保證整數和浮點數是32位的,但你不能只用vec4並假裝它是別的。

但是,OpenGL 3.3+確實允許您重新解釋單個標量值。首先,你的代碼應該使用整數緩衝區紋理,而不是浮點紋理。這只是爲了防止texel fetch邏輯在denomralized值,NaN或其他浮點奇怪的情況下做一些不愉快的事情。因此,您應該使用usamplerBuffer並取回uvec4

要獲得實際值,你必須做到位的重新解釋,通過適當的庫函數提供:

struct Data 
{ 
    int first; 
    float value; 
    int second; 
    int half1; 
    int half2; 
}; 

Data UnpackStruct(uvec4 packed) 
{ 
    Data ret; 
    ret.first = int(packed[0]); //Sign bit is preserved, per GLSL standard. 
    ret.value = uintBitsToFloat(packed[1]); 
    ret.second = int(packed[2]); 
    ret.half1 = (packed[3] >> 16) & 0x0000FFFF; 
    ret.half2 = packed[3] & 0x0000FFFF; 
    return ret; 
} 
+0

感謝提uintBitsToFloat;我忽略了這一點,之後我意識到我正在看GLSL 1.5參考卡。這大概是OpenCL如何使得全局緩衝區訪問對結構體的靈活性變得如此靈活? – user515655

相關問題