GLSL预处理器
我试图找出为什么以下 GLSL 代码不起作用:
#ifndef VertexPositionType
#define VertexPositionType vec3
#endif
in StandardVertexShaderInputs {
VertexPositionType ds_VertexPosition;
};
vec4 ProjectVertexPosition(in vec4 v);
vec4 ProjectVertexPosition(in vec3 v);
void main() {
gl_Position = ProjectVertexPosition(ds_VertexPosition);
}
着色器拒绝编译。信息日志状态:
错误 C1008:未定义变量“ProjectVertexPosition”
即使它没有警告有关预处理器的信息,我也发现预处理器符号 VertexPositionType 未被替换。如果我删除预处理器定义,一切都很好。
现在,规范说:
#define 和 #undef 功能按照 C++ 预处理器的标准定义,用于带宏和不带宏的宏定义 参数。
也许以下行不是有效的预处理器行?
#define VertexPositionType vec3
I'm trying to figure out why the following GLSL code doesn't work:
#ifndef VertexPositionType
#define VertexPositionType vec3
#endif
in StandardVertexShaderInputs {
VertexPositionType ds_VertexPosition;
};
vec4 ProjectVertexPosition(in vec4 v);
vec4 ProjectVertexPosition(in vec3 v);
void main() {
gl_Position = ProjectVertexPosition(ds_VertexPosition);
}
The shader refuse to compile. The info log state:
error C1008: undefined variable "ProjectVertexPosition"
Even if it doesn't warn about the preprocessor, I got that the preprocessor symbol VertexPositionType is not replaced. If I remove the preprocessor definitions, everything is fine.
Now, the specification says:
#define and #undef functionality are defined as is standard for C++ preprocessors for macro definitions both with and without macro
parameters.
Perhaps the following line is not a valid preprocessor line?
#define VertexPositionType vec3
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
你的着色器是非法的。 NVIDIA 的编译器可能不会吐出正确的错误,但您的着色器正在做错误的事情(好吧,除了您没有提供
#version
声明这一事实之外。我假设#version 330
,但明确 GLSL 版本总是好的)。我只能假设这是一个顶点着色器,因为您正在写入
gl_Position
。输入接口块在顶点着色器中是非法的,就像输出接口块在片段着色器中是非法的一样。 AMD 的编译器对此更加明确:当我删除接口块定义,将其保留在 VertexPositionType ds_VertexPosition; 中时,它编译得很好。
那么恭喜您:您发现了 NVIDIA 驱动程序错误。您应该向他们报告,因为顶点着色器中不允许输入接口块。
Your shader is illegal. NVIDIA's compiler may not be spitting out the right errors, but your shader is doing the wrong thing (well, besides the fact that you didn't provide a
#version
declaration. I assumed#version 330
, but it's always good to be explicit about GLSL versions).I can only assume this is a vertex shader, since you're writing to
gl_Position
. Input interface blocks are illegal in vertex shaders, just as output interface blocks are illegal in fragment shaders. AMD's compiler is rather more explicit about this:When I removed the interface block definition, leaving it as just
in VertexPositionType ds_VertexPosition;
, it compiled fine.Then congratulations: you have found an NVIDIA driver bug. You should report it to them, because input interface blocks are not allowed in vertex shaders.
您已经声明了一个名为 ProjectVertexPosition 的重载函数,但从未定义过它,因此当您链接程序时,您会收到未定义的错误。对于错误来说,说“未定义的函数”而不是“未定义的变量”可能更有意义(因为您将其声明为函数。),但我猜测链接器没有保留足够的信息来了解 a 之间的区别函数符号和变量符号。
此错误可能来自 LinkProgram 调用,而不是 CompileShader 调用,并且与预处理器或 VertexPositionType 无关
You've declared an overloaded function called ProjectVertexPosition, but you've never defined it, so when you go to link your program, you get the undefined error. It might make more sense for the error to say 'undefined function' rather than 'undefined variable' (since you declared it as a function.), but I'm guessing the linker doesn't keep enough info to know the difference between a function symbol and a variable symbol.
This error is probably coming from the LinkProgram call, not the CompileShader call, and has nothing to do with the preprocessor or VertexPositionType
您的程序有两个主要问题。
#define
不是你的问题。第一个问题是您从未提供 vec4 ProjectVertexPosition(in vec# v) 函数的实现。您需要提供一个声明,例如in vec4 v
版本。删除定义可以解决问题的原因是它使着色器忽略输入块,而输入块一开始就是无效的。在顶点着色器中,不能使用in
块。相反,使用布局和结构或制服和结构。对于顶点着色器,您只需要使用制服或布局,而不是纯粹的in
。如果要使用布局,请执行以下操作:对于 C/C++ 端,执行以下操作(其中 pointCount 是 VAO 中的点数,points 是包含按顺序 x1、y1、z1、x2 的点的 GLfloat* 、y2、z2、x3...:
Your program has two major problems.
The
#define
is not your problem. The first problem is you never provide an implementation of eithervec4 ProjectVertexPosition(in vec# v)
functions. You need to provide a declaration, for exampleand also for the
in vec4 v
version. The reason why removing the define fixes your problem is it makes the shader ignore the input block, which is invalid to begin with. In the vertex shader, you cant usein
blocks. Instead, use layouts and structs or uniforms and structs. For vertex shaders, you need to use uniforms or layouts only, not purein
s. If you want to use layouts, do the following:For the C/C++ side, do the following (where pointCount is the number of points in your VAO and points is a GLfloat* containing the points in order x1, y1, z1, x2, y2, z2, x3...: