Я испытываю странную проблему в 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
и членов модели, но в качестве проверки работоспособности я попытался инициализировать их по значению. Поведение было точно таким же, как и должно быть — почему было бы использование значения дает другой результат, чем переменная, инициализированная этим значением? Даже если я сыграю адвоката дьявола и предположу, что есть какая-то разница, почему эта же проблема не повлияет на отдельные «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));
Других решений пока нет …