Я полагаю, что это своего рода нечто среднее между вопросом о чистом языке C ++ и вопросом OpenGL. У меня есть единый буфер, и я выделяю в нем пространство размером байтов (ShaderData). Я использую макет std140 на стороне графического процессора в шейдере.
Согласно правилам std140, мне нужно добавить отступы в разных местах в моей структуре, чтобы убедиться, что такие вещи, как векторы, выровнены правильно. Структура ниже является примером (для моего света):
struct ShaderData {
float Light_Intensity;
float _pad1[3]; // align following vec3 on 4N boundary
Math::Vec3f Light_Position;
float _pad2; // align following vec4 on 4N boundary
Math::Colour4f Light_Ambient;
Math::Colour4f Light_Diffuse;
Math::Colour4f Light_Specular;
float Light_AttenuationMin;
float Light_AttenuationMax;
} MyShaderData;
Это люди обычно делают в C ++, или есть специальные ключевые слова или прагмы для выравнивания отдельных элементов структуры ЦП, которые немного более аккуратны?
Нет, таким образом, вы просто тратите пространство. Вы должны найти оптимизированный макет в соответствии с правилами std140.
float
нужно 4 байта и выровнено 4 байтаvec3
нужно 12 байтов и выровнено 16 байтовvec4
нужно 16 байтов и выровнено 16 байтовЭто означает, что вы можете найти лучший макет для вашей структуры:
float Light_Intensity; X
float _pad1[3]; XXX
Math::Vec3f Light_Position; XXX
float _pad2; X
Как вы можете видеть, вы тратите 4 байта, и что еще хуже, вы можете сделать что-то вроде:
Math::Vec3f Light_Position XXX
float Light_Intensity; X
Чтобы выровнять его и без необходимости тратить байт. Это работает, потому что vec3
будет выровнен по 16 байтовым границам, в то время как float
будет по-прежнему выровнен по 4 байтовым границам.
Других решений пока нет …