开发者

c++ bit flags in opengl shaders (glsl)

开发者 https://www.devze.com 2023-02-15 15:34 出处:网络
What would be the best way to send my bit flag to the fragment shader in order to be able to if() against it?

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

精彩评论

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