开发者

c++ bit flags in opengl shaders (glsl)

What would be the best way to send my bit flag to the fragment shader in order to be able to if() against it?

I have the following bit flag (enum):

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
    };

Corresponding to the table [] = place i,j in table ([bit as int])

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

So a possible value for my bitflag (options) when of every row in my actual table all first options are selected would give me a value of 273. In every row only one option can be selected.

Now when I want to check what options are enabled on the CPU using the bitflag I can simply do the following (for the example case where the first column is selected):

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

The idea is to, based upon the selection presented in the bitflag, execute different parts of the shader. For this purpose I need to do something like:

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

and skip (in the shader) the rest of the options which are disabled. However, in the ideal case I would like to simplify this to how it is done on the CPU, using the bitflags. So in my shader I 开发者_如何学Cwould like to have something along the lines of:

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

Is it possible to achieve something like this. Not the exact same thing maybe but something more elegant than simply " if()-ing " against all possible integers resulting from the bitflag? (like: if(1+16+256), if(1 + 16 + 512),... if(8+128+2048))


There will be no point in elegant enumeration of your flags because of the different code paths that you want to use. In C++ you could do something like a jump function table, but in GLSL you can't do that (and believe me - you don't want to). So check in a regular way:

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

As an alternative in case you are not bound to the Uber-shader approach - consider building the GLSL program from separate function blocks implemented in GLSL objects.

For example, one block may implement a regular renderer while the second do it in a photorealistic way. Both should have the same function name, that is linked externally in a main shader and called from there. When linking the GLSL program you attach only one of these blocks that matches desired behavior.


Can you use this?

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

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜