GLSL预处理器

发布于 2024-12-09 14:46:07 字数 753 浏览 0 评论 0原文

我试图找出为什么以下 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 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

昔梦 2024-12-16 14:46:07

你的着色器是非法的。 NVIDIA 的编译器可能不会吐出正确的错误,但您的着色器正在做错误的事情(好吧,除了您没有提供 #version 声明这一事实之外。我假设 #version 330,但明确 GLSL 版本总是好的)。

我只能假设这是一个顶点着色器,因为您正在写入 gl_Position。输入接口块在顶点着色器中是非法的,就像输出接口块在片段着色器中是非法的一样。 AMD 的编译器对此更加明确:

ERROR: 0:5: error(#328) interface block should not apply in 'Vertex Shader in'.
ERROR: 0:14: error(#143) Undeclared identifier ds_VertexPosition
ERROR: 0:14: error(#202) No matching overloaded function found ProjectVertexPosition
ERROR: 0:14: error(#160) Cannot convert from 'const float' to 'Position 4-component vector of float'
ERROR: error(#273) 4 compilation errors.  No code generated

当我删除接口块定义,将其保留在 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:

ERROR: 0:5: error(#328) interface block should not apply in 'Vertex Shader in'.
ERROR: 0:14: error(#143) Undeclared identifier ds_VertexPosition
ERROR: 0:14: error(#202) No matching overloaded function found ProjectVertexPosition
ERROR: 0:14: error(#160) Cannot convert from 'const float' to 'Position 4-component vector of float'
ERROR: error(#273) 4 compilation errors.  No code generated

When I removed the interface block definition, leaving it as just in VertexPositionType ds_VertexPosition;, it compiled fine.

If I remove the preprocessor definitions, everything is 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.

旧伤慢歌 2024-12-16 14:46:07

您已经声明了一个名为 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

乖乖 2024-12-16 14:46:07

您的程序有两个主要问题。
#define 不是你的问题。第一个问题是您从未提供 vec4 ProjectVertexPosition(in vec# v) 函数的实现。您需要提供一个声明,例如

vec4 ProjectVertexPosition(in vec3 v) {
    return normalize(vec4(v, 1.0));
}

in vec4 v 版本。删除定义可以解决问题的原因是它使着色器忽略输入块,而输入块一开始就是无效的。在顶点着色器中,不能使用 in 块。相反,使用布局和结构或制服和结构。对于顶点着色器,您只需要使用制服或布局,而不是纯粹的in。如果要使用布局,请执行以下操作:

layout(location = 0) in VertexPositionType ds_VertexPosition;

对于 C/C++ 端,执行以下操作(其中 pointCount 是 VAO 中的点数,points 是包含按顺序 x1、y1、z1、x2 的点的 GLfloat* 、y2、z2、x3...:

GLfloat* points = (GLfloat*) malloc(pointCount * 3 * sizeof(GLfloat));
// Set your points however you want here

GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 3 * pointCount * sizeof(GLfloat), points, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
free(points);

// Now to draw (use whatever programId is returned when you link the program)
glUseProgram(programId);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, pointCount);
glUseProgram(0);

Your program has two major problems.
The #define is not your problem. The first problem is you never provide an implementation of either vec4 ProjectVertexPosition(in vec# v) functions. You need to provide a declaration, for example

vec4 ProjectVertexPosition(in vec3 v) {
    return normalize(vec4(v, 1.0));
}

and 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 use in blocks. Instead, use layouts and structs or uniforms and structs. For vertex shaders, you need to use uniforms or layouts only, not pure ins. If you want to use layouts, do the following:

layout(location = 0) in VertexPositionType ds_VertexPosition;

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...:

GLfloat* points = (GLfloat*) malloc(pointCount * 3 * sizeof(GLfloat));
// Set your points however you want here

GLuint vao;
glGenVertexArrays(1, &vao);
glBindVertexArray(vao);

GLuint vbo;
glGenBuffers(1, &vbo);
glBindBuffer(GL_ARRAY_BUFFER, vbo);
glBufferData(GL_ARRAY_BUFFER, 3 * pointCount * sizeof(GLfloat), points, GL_STATIC_DRAW);
glVertexAttribPointer(0, 3, GL_FLOAT, GL_FALSE, 0, NULL);
glEnableVertexAttribArray(0);
free(points);

// Now to draw (use whatever programId is returned when you link the program)
glUseProgram(programId);
glBindVertexArray(vao);
glDrawArrays(GL_TRIANGLES, 0, pointCount);
glUseProgram(0);
~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文