c++ - 在 GLSL(330 或其他)中,什么会导致统一结构的行为不同于可变结构?

标签 c++ opengl glsl sanity-check

我在 OpenGL 3.3 中遇到了一个奇怪的问题。我用 vec4 成员“u”和“v”定义了一个名为 Dual 的结构,并开始编写和测试函数,就像稍后您将看到的“三明治产品”我的代码片段(我包括了实现,但它应该是无关紧要的。)在这个测试中,我使用了两个单独的 vec4 制服,称它们为“u”和“v”以明确它们 future 的目的,并且简单地从这些中即时制作双胞胎。当我对行为感到满意时,我制作了一个统一的 Dual,称为“模型”(如在模型- View -投影中),并着手将对独立 vector 的引用交换为对模型成员的引用。我遇到黑屏,但没有错误。

我已经重新设计了我的顶点着色器,直到可以通过在两行上切换注释来启用/禁用该问题:

#version 330

struct Dual { vec4 u, v; };

// (...)

// This should be agnostic to where the args come from
// It was and is correct given local variables/values
Dual sandwich(Dual u, Dual v) { return mul(mul(u, v), conj(u)); }

uniform mat4 projection;

const vec4 u0 = vec4(1,0,0,0), v0 = vec4(0,0,0,0);
uniform vec4 u = u0, v = v0;
uniform Dual model = Dual(u0, v0);

in vec4 pos_in;
out vec4 pos_out;

void main(){
        // Swizzling 'xyz' and then 'yzw' adapts GLSL 'xyzw' to/from 'wxyz'
        // It may look strange, but again, it works for local values
        Dual x = Dual(u0, vec4(0, pos_in.xyz)),
                // mxm = sandwich(model, x); // -> big black canvas
                mxm = sandwich(Dual(u, v), x); // -> big rainbow square
        gl_Position = projection * vec4(mxm.v.yzw, 1);
        pos_out = gl_Position;
}

在我的 C++ 代码中,我尝试在初始化后设置一次值,每次按键一次到不同的预设,甚至每帧一次,但现在我依赖着色器中的默认初始化,直到我按下键 - 这是它的样子:

auto mu = program.locate("model.u"), mv = program.locate("model.v"),
        u = program.locate("u"), v = program.locate("v");
// ...key 1 is pressed, so set both pairs to the Dual identity...
glUniform4f(mu, 1, 0, 0, 0); glUniform4f(mv, 0, 0, 0, 0);
glUniform4f(u, 1, 0, 0, 0);  glUniform4f(v, 0, 0, 0, 0);
// ...key 2 is pressed, set both to something else, and so on

当然,我的第一个猜测是我错误地定位了成员,但这是我在其他地方看到的语法,而且我也没有看到拼写错误。由于没有与未知名称相关的错误,我检查了 telltale -1 的位置,但 model.umodel.v 分别报告 0 和 1。

使用常量“u0”和“v0”来初始化 vec4 和模型的成员,但作为一种完整性检查,我尝试按值初始化它们。行为完全相同,因为它应该是 - 为什么 使用一个值会产生与初始化为该值的变量不同的结果?即使我唱反调并假设存在一些差异,为什么当独立的“u”和“v”被初始化为命名变量“u0”和“v0”而不是他们被赋予的值(value)观?

感谢您的宝贵时间。我觉得如果我只是接受这种行为并继续前进,我就是未通过健全性检查的人。

最佳答案

const vec4 u0 = vec4(1,0,0,0), v0 = vec4(0,0,0,0);
uniform vec4 u = u0, v = v0;
uniform Dual model = Dual(u0, v0);

这三行初始化u0, v0, u, v, model。这些具有提供值的初始化在链接时完成。

我在 GLSL 规范中找不到关于全局变量顺序的字眼。我找到的最接近的是 4.2 Scoping:

Within a declaration, the scope of a name starts immediately after the initializer if present or immediately after the name being declared if not.

但是“范围”与“顺序或初始化”不同。

所以可能 modelu0, v0 之前被初始化,所以这些值是未定义的。

安全的方法(不依赖于不同供应商的实现)不依赖于其他全局变量,而是使用:

uniform Dual model = Dual(vec4(1,0,0,0), vec4(0,0,0,0));

关于c++ - 在 GLSL(330 或其他)中,什么会导致统一结构的行为不同于可变结构?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/52102304/

相关文章:

c++ - 在 noexcept 函数体中处理 std::optional 是否安全?

opengl - 使用统一的 sampler2d[] 时出现无法解释的行为

c++ - Qt 4.6 OpenGL GLSL

rust - 是否可以在运行时编译Vulkano着色器?

c++ - 在 OpenGL/GLSL 中绘制镶嵌的 LineLoops

c++ - 嵌入式STL智能指针

c++ nlohmann json - 如何测试嵌套对象是否存在或为空

c++ - Save the IP of a domain to a txt file/Save my dynamic ip to a txt file with c++ 或批处理

ios - 从 OpenGL 移植到 MetalKit - 投影矩阵(?)问题

opengl - 应用程序如何支持多个图形 API?