2011-03-09 94 views
1

什麼是我的位標誌發送到片段着色器,以便能夠IF()反對它的最佳方式?C++在OpenGL着色器(GLSL)位標誌

我有以下比特的標誌(枚舉):

uint32_t options; 

enum Options { 
    ON     = 1 << 0, /// row 1 | enable or disable 
    OFF     = 1 << 1, 
    DUMMY1    = 1 << 2, 
    DUMMY2    = 1 << 3, 
    NONE    = 1 << 4, /// row 2 | contours 
    SILHOUETTE   = 1 << 5, 
    SUGGESTIVE   = 1 << 6, 
    APPARENTRIDGES  = 1 << 7, 
    PHOTOREALISTIC  = 1 << 8, /// row 3 | shading 
    TONE    = 1 << 9, 
    TONESPLASHBACK  = 1 << 10, 
    EXAGGERATED   = 1 << 11 
    }; 

對應於表格[] =地方I,J在表([比特作爲INT])

[1] [2] [4] [8] 
[16] [32] [64] [128] 
[256] [512] [1024] [2048] 

因此,一個我的位標誌(選項)可能值在我的實際表中每一行的所有第一選項被選中會給我的273的值。在只有一個選項可以選擇每一行的時候。

現在,當我想用​​位標誌,我可以簡單地做以下(用於在選擇第一列中的例子的情況下),以檢查哪些選項是在CPU上啓用:

if (options & ON) {}   // true 
if (options & OFF) {}   // false 
if (options & PHOTOREALISTIC) // true 

的想法是基於bitflag中的選擇,執行着色器的不同部分。爲此,我需要執行如下操作:

if(options == 273) 
    // do enable object, render with no contours and in a photorealistic manner 

並跳過(在着色器中)禁用的其餘選項。但是,在理想的情況下,我想簡化它到如何在CPU上完成,使用位標誌。所以在我的着色器中,我想沿用以下幾行:

if ((options & PHOTOREALISTIC) & (options & ON)) // true 
    // do stuff 

是否有可能實現類似這樣的事情。不是完全相同的東西,但可能比「if() - ing」針對bitflag產生的所有可能整數更優雅? (如:如果(1 + 16 + 256),如果(1 + 16 + 512),......如果(8 + 128 + 2048))

+0

可以傳遞整數制服着色器,並在着色器執行整數(按位)操作。究竟是什麼麻煩? – 2011-03-09 20:51:31

+0

呃,我不認爲這樣的簡單的解決方案,作爲送我的枚舉校服,以爲我是被迫寫的選項==值,而不是選擇與(制服| uniform2)(制服是我的枚舉)= [ 。 – bastijn 2011-03-10 08:38:25

回答

3

由於您想要使用不同的代碼路徑,因此優雅的枚舉枚舉將毫無意義。在C++中,你可以做一些跳轉函數表,但在GLSL中你不能這麼做(並且相信我 - 你不想這麼做)。因此,檢查的正常做法:

if (options & (ON | PHOTOREALISTIC)) { /*do something*/ } 

正如你不一定要尤伯杯着色器方法的情況下一個選擇 - 考慮建立從GLSL對象實現獨立功能塊GLSL程序。

例如,而第二在逼真的方式這樣做一個塊可以實現常規的渲染器。兩者應具有相同的函數名稱,該名稱在主着色器中外部鏈接並從那裏調用。鏈接GLSL程序時,只附加符合所需行爲的塊之一。

+0

如何在GLSL中創建單獨的編譯塊? – 2013-07-01 08:53:58

+0

GLSL程序以與C鏈接非常相​​似的方式從GLSL對象鏈接。基本上,您可以編譯一組對象,將它們附加到程序中,然後將它們鏈接在一起。每個對象都可以訪問同一着色器階段(無論是頂點,片段等)的其他對象的函數。 – kvark 2013-11-14 15:06:18

0

,你可以用這個?

if ((options & (PHOTOREALISTIC | ON)) == (PHOTOREALISTIC | ON))