【问题标题】:Why won't fragment shader compile?为什么片段着色器不能编译?
【发布时间】:2018-03-05 19:22:54
【问题描述】:

我在许多 Windows 7 和 8 PC 上使用了以下片段着色器,没有问题。

#ifndef STRINGIFY
#define STRINGIFY(a) #a
#endif

char *fsFont  = STRINGIFY(

precision mediump float;
varying vec2 v_texCoord;
vec2 v_texCoord;
uniform sampler2D s_texture;
uniform vec4      vColor4;

varying lowp vec4 DestinationColor;

void main()
{
  gl_FragColor = vec4( 1, 1, 1, texture2D( s_texture, v_texCoord).a ) * vColor4;
}

);

最近我尝试在 Windows 10 机器上运行我的应用程序,但在尝试编译着色器时出现以下错误:

0x0059f3dc "0(1) : warning C7022: unrecognized profile specifier "mediump"
0(1) : warning C7022: unrecognized profile specifier "precision"
0(1) : error C1038: declaration of "v_texCoord" conflicts with previous declaration at 0(1)
0(1) : error C0000: syntax error, u"

如果我注释掉 precision mediump float 行..

0x0137f2c8 "0(1) : error C0000: syntax error, unexpected identifier, expecting "::" at token "lowp"
"

有什么问题?是不是因为我使用的 PC 支持的 OpenGL 版本与我预期的不同?

更新This post 建议精度 mediump 浮点线仅适用于 OpenGL ES。这仍然无法解释为什么它可以在我的大多数 PC 上运行。继续,lowp 声明有什么问题?

这是我选择 OpenGL 配置文件/版本的 SDL 初始化代码:

#ifndef _WIN32
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_ES );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 2 );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 0 );
#else
  // Use OpenGL 3.1 core 
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MAJOR_VERSION, 3 );
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_MINOR_VERSION, 1 ); 
  SDL_GL_SetAttribute( SDL_GL_CONTEXT_PROFILE_MASK, SDL_GL_CONTEXT_PROFILE_CORE );
#endif

更新:这是更新后的着色器,感谢大家的 cmets,它现在可以正常工作:

char *fsFont  = 

"#version 330\n"
"precision mediump float;\n"
"varying vec2 v_texCoord;\n"

"uniform sampler2D s_texture;"
"uniform vec4      vColor4;"

"varying lowp vec4 DestinationColor;"

"void main()"
"{"
  "gl_FragColor = vec4( 1, 1, 1, texture2D( s_texture, v_texCoord).a ) * vColor4;"
"}"

;                 

更新:我已从所有着色器中删除了 STRINGIFY,移至 OpenGL 3.3。我所有的着色器都编译了一个例外:

    char *vs3DShader  = 

    "#version 330\n"
    "layout (location = 0) in vec3 Position;"
    "layout (location = 1) in vec4 color;"
    "layout (location = 2) in vec3 normal;"

    "out vec4 frag_color;"

    "uniform mat4 transform;"

    "void main()"
    "{"
    "  gl_Position = transform * vec4( Position.x, Position.y, Position.z, 1.0 );"

    "  // Pass vertex color to fragment shader.."
    "  frag_color = color;"
    "}"
;

错误:

0x0055f370 "(0) : error C0000: syntax error, unexpected $end at token "<EOF>"
"

【问题讨论】:

  • 您的目标是哪个 OpenGL 配置文件?在 OpenGL3 Core Profile 中,没有 varying 关键字。 v_texCoord 应该是什么?您还缺少#version ... 行。
  • 请阅读错误信息。变量v_texCoord 被声明了两次!
  • 没有#version 指令意味着#version 110 这很少是你想要的。所以总是指定。
  • @SparkyNZ:当你需要做这样的事情时,请使用原始字符串文字,而不是“STRINGIFY”宏。
  • 我仍然高度怀疑一切是否正常。如果您真的使用#version 330,那么您应该会遇到大量错误,因为varying 已被删除并替换为in/out。同样使用带有 3.3 着色器的 OpenGL 3.1 听起来很可疑。

标签: c++ opengl fragment-shader opengl-3


【解决方案1】:

着色器无法编译,因为:

  • 着色器源中没有 #version 行(版本未定义,可能是不同机器上的任何默认值)
  • STRINGIFY() 宏不适用于 # 字符,因此最好将着色器作为文本从文件加载或在每行周围用双引号指定它​​,记住在以 '@987654326 开头的行之后使用 \n @' 或 cmets - 最好每行都安全
  • 尝试删除STRINGIFY() 时,必须在任何 cmets 后添加换行符,否则注释后附加的所有内容都将被注释掉
  • 在试图找出为什么会为 mediumpvarying 关键字生成警告/错误时引入了重复变量
  • 必须使用正确的 GLSL #version,它与 this table 中的 genpfault 所指示的 OpenGL 版本相对应(即 OpenGL3.1 必须使用 #version 140

【讨论】:

    猜你喜欢
    • 2018-07-02
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2021-04-21
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多