C++在OpenGL着色器(GLSL)位标志

问题描述:

什么是我的位标志发送到片段着色器,以便能够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”针对bitfla*生的所有可能整数更优雅? (如:如果(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

由于您想要使用不同的代码路径,因此优雅的枚举枚举将毫无意义。在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

,你可以用这个?

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