opengl GLSL错误:“##”:不支持这些令牌

jk9hmnmh  于 2023-06-29  发布在  其他
关注(0)|答案(2)|浏览(154)

我有一个AMD Radeon Graphics(Ryzen 7000)GPU,我正在使用OpenGL创建一个程序。我在GLSL版本330中编写了着色器,并启用了扩展GL_ARB_shading_language_420pack。但是,当在宏函数中使用##运算符时,我收到以下错误:

'##' : not supported for these tokens

即使我使用更高的GLSL版本,如420,问题仍然存在。(我使用330是为了兼容性。
问题代码:

#define calc_channel( n )                                                                                                                    \
{                                                                                                                                            \
    vec3 enable_light_rgb = vec3( chan_ctrl##n##_color_light_enable, chan_ctrl##n##_color_light_enable, chan_ctrl##n##_color_light_enable ); \
    vec3 light_color_rgb = clamp( diffuse_light.rgb + amb_color##n.rgb * cAmbColor[##n].rgb, 0.0, 1.0 );                                     \
    float light_color_a  = clamp( diffuse_light.a   + amb_color##n.a,                        0.0, 1.0 );                                     \
    color##n##a##n.rgb = chan_ctrl##n##_color.rgb * max( enable_light_rgb, light_color_rgb );                                                \
    color##n##a##n.a   = chan_ctrl##n##_alpha.a   * max( 1.0 - chan_ctrl##0##_alpha_light_enable, light_color_a );                           \
}

用法如下:

calc_channel( 0 );

我多次使用宏,而不是一次,因此它存在的原因。我把第一次出现的错误贴了出来。
让我知道如果任何更多的信息是必要的评论。
代码可以在我拥有的其他GPU上工作(Nvidia和Intel)。

编辑

您可能已经注意到上面的宏函数中存在以下复制粘贴错误:

chan_ctrl##0##_alpha_light_enable

这只是一个复制粘贴错误,而不是错误。这不是问题的根源,因为即使将其更换为chan_ctrl0_alpha_light_enable后,错误仍然存在。
有趣的是,我试图删除着色器代码的整个部分,看看其余部分是否可以编译,编译器仍然阻塞在使用##的不同宏函数上,但方式不同。
macro函数:

#define calc_tex_coord( n )                                        \
{                                                                  \
    expand_tex_func( n );                                          \
    tex_coord##n##.x = dot( expand_tex_mtx( n )[ 0 ], tex_coord ); \
    tex_coord##n##.y = dot( expand_tex_mtx( n )[ 1 ], tex_coord ); \
    float tw         = dot( expand_tex_mtx( n )[ 2 ], tex_coord ); \
}

用法如下:

calc_tex_coord( 0 );

有趣的部分是我得到的错误:

ERROR: 0:355: 'tex_coord0nx' : undeclared identifier
ERROR: 0:355: 'tex_coord0ny' : undeclared identifier
ERROR: 0:355: '' : missing #endif
ERROR: 0:355: '' : compilation terminated
ERROR: 4 compilation errors.  No code generated.

这一次,它没有抱怨##运算符。但是,它错误地将令牌tex_coord##n##.xtex_coord##n##.y扩展为tex_coord0nxtex_coord0ny,而不是tex_coord0.xtex_coord0.y

编辑2

我得到了一个朋友与不同的Radeon(AMD Radeon RX 5500 XT),他能够得到更详细的错误信息。
对于第一个宏函数,他得到:

Pasting "[" and "0" does not give a valid preprocessing token.

(Note ##0##不会出错。
对于第二个宏函数,它实际上正确地粘贴了0n),但仍然卡住了:

Pasting "tex_coord0" and "." does not give a valid preprocessing token.
kq4fsx7k

kq4fsx7k1#

看起来AMD预处理器只支持使用##,其中运算符的一个操作数是宏的参数,这是严格正确的C和GLSL语言规范。您的宏具有以下表达式:

chan_ctrl##0##_alpha_light_enable

它试图粘贴一些不包括参数的标记。如果你把它换成

chan_ctrl0_alpha_light_enable

可能会有用。

2admgd59

2admgd592#

显然,AMD预处理器有以下两个部分的问题:

  • cAmbColor[##n].rgb
  • tex_coord##n##.x

在前者中,不喜欢在[之后使用##。在后者中,它不喜欢在.之前使用##
两者之间的共同属性是AMD预处理器不喜欢粘贴宏参数和对标识符无效的符号。我对GLSL / C标准了解不多,不知道拒绝这一点是对是错。然而,事实上,原始代码在Nvidia,Intel和第三个专有着色器编译器的预处理器上运行良好。这只是AMD预处理器的抱怨。

相关问题