c++ - 在 GLSL(330 或其他)中,什么可能导致统一结构的行为与变量结构不同?
问题描述
我在 OpenGL 3.3 中遇到了一个奇怪的问题。我定义了一个Dual
用vec4
成员“u”和“v”调用的结构,并开始编写和测试函数,就像稍后将在我的片段中看到的“三明治产品”(我包含了实现,但它应该无关紧要。)在这次测试中,我使用了两个单独vec4
的制服,称它们为“u”和“v”,以明确他们未来的目的,并简单地从这些制服上制作 Duals。当我对这种行为感到满意时,我制作了一个统一的 Dual,称为“模型”(如在模型视图投影中),并着手交换对独立向量的引用以对模型成员的引用。我有一个黑屏,但没有错误。
我已经重新设计了我的顶点着色器,直到可以通过在两行上切换注释来启用/禁用该问题:
#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
当然,我的第一个猜测是我错误地定位了成员,但这是我在其他地方看到的语法,我也没有看到拼写错误。由于没有与未知名称相关的错误,我检查了告示符 -1 的位置,但model.u
分别model.v
报告了 0 和 1。
使用常量“u0”和“v0”来初始化vec4
s 和模型的成员,但作为一种健全性检查,我尝试按值初始化它们。行为完全一样,因为它应该是 - 为什么使用一个值会产生与初始化为该值的变量不同的结果?即使我扮演魔鬼的拥护者并假设存在一些差异,当独立的“u”和“v”被初始化为命名变量“u0”和“v0”时,为什么同样的问题不会影响它们?他们被赋予的价值?
感谢您的时间。我觉得如果我只是接受这种行为并继续前进,我就是那个没有通过理智检查的人。
解决方案
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 范围:
在声明中,名称的范围在初始化器(如果存在)之后立即开始,如果不存在,则在被声明的名称之后立即开始。
但是“范围”与“命令或初始化”不同。
所以它可能是model
之前被初始化的u0, v0
,所以这些值是未定义的。
安全的方式(不依赖于不同的供应商实现)不依赖于其他全局变量,而是使用:
uniform Dual model = Dual(vec4(1,0,0,0), vec4(0,0,0,0));
推荐阅读
- matlab - 使用 arrayfun 或其他方式创建动态 matlab 函数
- c# - 如何在逻辑层访问 ClaimsIdentity
- python - 在 def 中找不到文本变量
- python - MoviePy write_videofile 需要几个小时
- python - 在 Python 中更新列表列表中的特定列表
- web-crawler - 我的 robots.txt 文件中的以下语法是否会阻止所有爬虫将我的网站编入索引?
- python - 初学者 Python - 在列表中打印值
- firebase - Firebase,有什么比云调度程序更好的吗?
- python-3.x - Matplotlib 归零的刺在平移时伸出轴外
- python - 如何根据从文本文件导入的数据创建 Python 字典?